Subversion Repositories SmartDukaan

Rev

Rev 37172 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
28217 tejbeer 1
package com.smartdukaan.cron.scheduled;
23723 amit.gupta 2
 
34039 vikas.jang 3
import com.google.auth.oauth2.GoogleCredentials;
24542 amit.gupta 4
import com.google.common.collect.Lists;
25300 tejbeer 5
import com.google.gson.Gson;
29488 manish 6
import com.razorpay.Payment;
32421 amit.gupta 7
import com.smartdukaan.cron.itelImeiActivation.ItelImeiActivationNewService;
29488 manish 8
import com.smartdukaan.cron.itelImeiActivation.ItelImeiActivationService;
9
import com.smartdukaan.cron.itelImeiActivation.TecnoImeiActivation;
33994 amit.gupta 10
import com.smartdukaan.cron.migrations.RunOnceTasks;
35021 amit 11
import com.smartdukaan.cron.scheduled.ambreports.AbmReportSender;
36745 ranu 12
import com.smartdukaan.cron.scheduled.beatmiss.BeatMissDetectorRunner;
32482 amit.gupta 13
import com.smartdukaan.cron.scheduled.runnables.PurchaseMigration;
32511 amit.gupta 14
import com.spice.profitmandi.common.enumuration.*;
24121 govind 15
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
36561 amit 16
import org.springframework.scheduling.annotation.Scheduled;
32421 amit.gupta 17
import com.spice.profitmandi.common.model.*;
24681 amit.gupta 18
import com.spice.profitmandi.common.services.ReporticoService;
29814 tejbeer 19
import com.spice.profitmandi.common.services.mandii.MandiiService;
35295 amit 20
import com.spice.profitmandi.common.util.FileUtil;
21
import com.spice.profitmandi.common.util.FormattingUtils;
22
import com.spice.profitmandi.common.util.PdfUtils;
23
import com.spice.profitmandi.common.util.Utils;
24592 amit.gupta 24
import com.spice.profitmandi.common.util.Utils.Attachment;
29308 tejbeer 25
import com.spice.profitmandi.common.web.client.RestClient;
25300 tejbeer 26
import com.spice.profitmandi.dao.Interface.Campaign;
32511 amit.gupta 27
import com.spice.profitmandi.dao.cart.CartService;
34450 ranu 28
import com.spice.profitmandi.dao.cart.SmartCartService;
25590 amit.gupta 29
import com.spice.profitmandi.dao.entity.auth.AuthUser;
30421 tejbeer 30
import com.spice.profitmandi.dao.entity.auth.PartnerCollectionRemark;
33078 ranu 31
import com.spice.profitmandi.dao.entity.catalog.*;
35393 amit 32
import com.spice.profitmandi.dao.entity.catalog.Offer;
33078 ranu 33
import com.spice.profitmandi.dao.entity.cs.NonSdBuying;
25590 amit.gupta 34
import com.spice.profitmandi.dao.entity.cs.Position;
26283 tejbeer 35
import com.spice.profitmandi.dao.entity.cs.Ticket;
35295 amit 36
import com.spice.profitmandi.dao.entity.dtr.*;
28769 amit.gupta 37
import com.spice.profitmandi.dao.entity.dtr.User;
32421 amit.gupta 38
import com.spice.profitmandi.dao.entity.fofo.*;
39
import com.spice.profitmandi.dao.entity.inventory.*;
33553 ranu 40
import com.spice.profitmandi.dao.entity.logistics.AST;
41
import com.spice.profitmandi.dao.entity.logistics.ASTRepository;
32421 amit.gupta 42
import com.spice.profitmandi.dao.entity.transaction.*;
43
import com.spice.profitmandi.dao.entity.user.*;
32511 amit.gupta 44
import com.spice.profitmandi.dao.entity.warehouse.WarehouseInventoryItem;
45
import com.spice.profitmandi.dao.entity.warehouse.WarehouseScan;
30421 tejbeer 46
import com.spice.profitmandi.dao.enumuration.auth.CollectionRemark;
34324 amit.gupta 47
import com.spice.profitmandi.dao.enumuration.catalog.StockTransactionType;
25598 amit.gupta 48
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
26790 tejbeer 49
import com.spice.profitmandi.dao.enumuration.dtr.RefferalStatus;
29814 tejbeer 50
import com.spice.profitmandi.dao.enumuration.fofo.Gateway;
31332 amit.gupta 51
import com.spice.profitmandi.dao.enumuration.fofo.PaymentStatus;
32511 amit.gupta 52
import com.spice.profitmandi.dao.enumuration.fofo.ReturnType;
24242 amit.gupta 53
import com.spice.profitmandi.dao.enumuration.fofo.ScanType;
34162 ranu 54
import com.spice.profitmandi.dao.enumuration.inventory.CatalogMovingEnum;
32081 tejbeer 55
import com.spice.profitmandi.dao.enumuration.inventory.VendorCatalogPricingStatus;
34324 amit.gupta 56
import com.spice.profitmandi.dao.enumuration.transaction.CreditRisk;
57
import com.spice.profitmandi.dao.enumuration.transaction.LoanReferenceType;
58
import com.spice.profitmandi.dao.enumuration.transaction.PriceDropImeiStatus;
59
import com.spice.profitmandi.dao.enumuration.transaction.SchemePayoutStatus;
32421 amit.gupta 60
import com.spice.profitmandi.dao.model.*;
33452 amit.gupta 61
import com.spice.profitmandi.dao.repository.GenericRepository;
25590 amit.gupta 62
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
33078 ranu 63
import com.spice.profitmandi.dao.repository.auth.NonSdBuyingRepository;
30421 tejbeer 64
import com.spice.profitmandi.dao.repository.auth.PartnerCollectionRemarkRepository;
32421 amit.gupta 65
import com.spice.profitmandi.dao.repository.catalog.*;
33874 ranu 66
import com.spice.profitmandi.dao.repository.cs.CsService;
67
import com.spice.profitmandi.dao.repository.cs.PartnerRegionRepository;
68
import com.spice.profitmandi.dao.repository.cs.PositionRepository;
69
import com.spice.profitmandi.dao.repository.cs.TicketRepository;
32421 amit.gupta 70
import com.spice.profitmandi.dao.repository.dtr.*;
71
import com.spice.profitmandi.dao.repository.fofo.*;
72
import com.spice.profitmandi.dao.repository.inventory.*;
33817 amit.gupta 73
import com.spice.profitmandi.dao.repository.logistics.WarehouseProviderRepository;
32421 amit.gupta 74
import com.spice.profitmandi.dao.repository.transaction.*;
35295 amit 75
import com.spice.profitmandi.dao.repository.trialOnboarding.TrialFormRepository;
24542 amit.gupta 76
import com.spice.profitmandi.dao.repository.user.AddressRepository;
34160 tejus.loha 77
import com.spice.profitmandi.dao.repository.user.LoiFormRepository;
25721 tejbeer 78
import com.spice.profitmandi.dao.repository.user.UserRepository;
32421 amit.gupta 79
import com.spice.profitmandi.dao.repository.warehouse.*;
34547 vikas.jang 80
import com.spice.profitmandi.dao.service.LiquidationService;
34252 tejus.loha 81
import com.spice.profitmandi.dao.service.PurSaleService;
33355 amit.gupta 82
import com.spice.profitmandi.dao.service.SidbiService;
32817 amit.gupta 83
import com.spice.profitmandi.dao.service.biuedart.BluedartAuthService;
84
import com.spice.profitmandi.dao.service.biuedart.BluedartService;
35788 vikas 85
import com.spice.profitmandi.dao.service.shopify.ShopifyProductSyncService;
31604 tejbeer 86
import com.spice.profitmandi.dao.service.solr.FofoSolr;
32421 amit.gupta 87
import com.spice.profitmandi.service.*;
31332 amit.gupta 88
import com.spice.profitmandi.service.integrations.CCAvenuePaymentService;
28368 tejbeer 89
import com.spice.profitmandi.service.integrations.RazorpayPaymentService;
30858 amit.gupta 90
import com.spice.profitmandi.service.integrations.bharti.model.BAGInsuranceModel;
33638 amit.gupta 91
import com.spice.profitmandi.service.integrations.gstpro.GstProAuthService;
33817 amit.gupta 92
import com.spice.profitmandi.service.integrations.gstpro.GstProService;
35666 vikas 93
import com.spice.profitmandi.service.integrations.pinelabs.PinelabsAffordabilityService;
94
import com.spice.profitmandi.service.integrations.pinelabs.PinelabsAuthService;
95
import com.spice.profitmandi.service.integrations.pinelabs.PinelabsOfferCacheService;
35393 amit 96
import com.spice.profitmandi.service.integrations.pinelabs.dto.*;
32872 amit.gupta 97
import com.spice.profitmandi.service.integrations.psismart.PsiSmartService;
32948 amit.gupta 98
import com.spice.profitmandi.service.integrations.smartping.SmartPingService;
25694 amit.gupta 99
import com.spice.profitmandi.service.integrations.toffee.ToffeeService;
32421 amit.gupta 100
import com.spice.profitmandi.service.inventory.*;
37172 amit 101
import com.spice.profitmandi.service.AgendaSyncResult;
35959 amit 102
import com.spice.profitmandi.service.mail.MailOutboxService;
31746 amit.gupta 103
import com.spice.profitmandi.service.offers.OfferService;
25335 amit.gupta 104
import com.spice.profitmandi.service.order.OrderService;
33452 amit.gupta 105
import com.spice.profitmandi.service.pricecircular.PriceCircularService;
24431 amit.gupta 106
import com.spice.profitmandi.service.pricing.PriceDropService;
23724 amit.gupta 107
import com.spice.profitmandi.service.recharge.provider.OxigenRechargeProviderService;
108
import com.spice.profitmandi.service.recharge.provider.ThinkWalnutDigitalRechargeProviderService;
109
import com.spice.profitmandi.service.scheme.SchemeService;
29668 tejbeer 110
import com.spice.profitmandi.service.serviceConfig.ServiceConfigService;
35295 amit 111
import com.spice.profitmandi.service.transaction.CreditBlockedExceptionPartnersRepository;
31008 amit.gupta 112
import com.spice.profitmandi.service.transaction.CreditNoteService;
30859 tejbeer 113
import com.spice.profitmandi.service.transaction.SDCreditService;
23929 amit.gupta 114
import com.spice.profitmandi.service.transaction.TransactionService;
32990 amit.gupta 115
import com.spice.profitmandi.service.transaction.invoicing.InvoiceService;
23929 amit.gupta 116
import com.spice.profitmandi.service.user.RetailerService;
34160 tejus.loha 117
import com.spice.profitmandi.service.user.StoreTimelineTatService;
32511 amit.gupta 118
import com.spice.profitmandi.service.wallet.CommonPaymentService;
23739 amit.gupta 119
import com.spice.profitmandi.service.wallet.WalletService;
32421 amit.gupta 120
import com.spice.profitmandi.service.warehouse.PurchaseOrderService;
32511 amit.gupta 121
import com.spice.profitmandi.service.warehouse.WarehouseInventoryService;
33384 amit.gupta 122
import com.spice.profitmandi.service.warehouse.WarehouseService;
25721 tejbeer 123
import in.shop2020.model.v1.order.OrderStatus;
29308 tejbeer 124
import in.shop2020.model.v1.order.WalletReferenceType;
32421 amit.gupta 125
import org.apache.commons.io.output.ByteArrayOutputStream;
126
import org.apache.commons.lang.StringUtils;
127
import org.apache.http.client.methods.CloseableHttpResponse;
128
import org.apache.http.client.methods.HttpPost;
129
import org.apache.http.conn.HttpHostConnectException;
130
import org.apache.http.entity.StringEntity;
131
import org.apache.http.impl.client.CloseableHttpClient;
36420 amit 132
import com.spice.profitmandi.common.web.client.HttpClientFactory;
32421 amit.gupta 133
import org.apache.logging.log4j.LogManager;
134
import org.apache.logging.log4j.Logger;
135
import org.hibernate.SessionFactory;
136
import org.json.JSONObject;
137
import org.springframework.beans.factory.annotation.Autowired;
138
import org.springframework.beans.factory.annotation.Qualifier;
139
import org.springframework.beans.factory.annotation.Value;
140
import org.springframework.core.io.ByteArrayResource;
141
import org.springframework.core.io.InputStreamSource;
142
import org.springframework.mail.javamail.JavaMailSender;
143
import org.springframework.mail.javamail.MimeMessageHelper;
144
import org.springframework.stereotype.Component;
145
import org.springframework.transaction.annotation.Transactional;
31640 tejbeer 146
 
32421 amit.gupta 147
import javax.mail.MessagingException;
148
import javax.mail.internet.InternetAddress;
149
import javax.mail.internet.MimeMessage;
150
import java.io.*;
151
import java.math.BigDecimal;
152
import java.math.RoundingMode;
153
import java.nio.file.Files;
154
import java.nio.file.Paths;
155
import java.sql.Timestamp;
156
import java.text.DecimalFormat;
157
import java.time.*;
158
import java.time.format.DateTimeFormatter;
159
import java.time.temporal.ChronoField;
160
import java.time.temporal.ChronoUnit;
161
import java.util.*;
162
import java.util.Map.Entry;
163
import java.util.stream.Collectors;
164
import java.util.stream.Stream;
32060 amit.gupta 165
 
33664 amit.gupta 166
import static java.util.stream.Collectors.*;
32421 amit.gupta 167
 
168
 
23723 amit.gupta 169
@Component
33384 amit.gupta 170
@Transactional(rollbackFor = {Throwable.class, ProfitMandiBusinessException.class})
23723 amit.gupta 171
public class ScheduledTasks {
172
 
36289 amit 173
    // Lock to serialize all methods that write to sd_credit_requirement table.
174
    // Prevents deadlocks and stale-data overwrites from concurrent cron threads.
175
    public static final Object SD_CREDIT_LOCK = new Object();
176
 
31697 amit.gupta 177
    @Value("${oxigen.recharge.enquiry.url}")
178
    private String oxigenRechargeEnquiryUrl;
24533 govind 179
 
31697 amit.gupta 180
    @Autowired
32482 amit.gupta 181
    PurchaseMigration purchaseMigration;
182
 
183
    @Autowired
36745 ranu 184
    private BeatMissDetectorRunner beatMissDetectorRunner;
185
 
186
    @Autowired
37172 amit 187
    private com.spice.profitmandi.service.AgendaAutoRuleService agendaAutoRuleService;
188
 
189
    @Autowired
32795 amit.gupta 190
    SmartPingService smartPingService;
191
 
33553 ranu 192
    @Autowired
193
    private ASTRepository astRepository;
29668 tejbeer 194
 
31697 amit.gupta 195
    @Autowired
196
    private ServiceConfigService serviceConfigService;
29801 manish 197
 
31697 amit.gupta 198
    @Autowired
199
    private TecnoImeiActivation tecnoImeiActivation;
28205 tejbeer 200
 
31697 amit.gupta 201
    private static final DateTimeFormatter leadTimeFormatter = DateTimeFormatter.ofPattern("d LLL, hh:mm a");
27088 tejbeer 202
 
31697 amit.gupta 203
    @Autowired
204
    private PartnerRegionRepository partnerRegionRepository;
28790 amit.gupta 205
 
31697 amit.gupta 206
    @Autowired
207
    private EmployeeAttendanceRepository employeeAttendanceRepository;
27088 tejbeer 208
 
31697 amit.gupta 209
    @Autowired
210
    VivoImeiActivationService vivoImeiActivationService;
29488 manish 211
 
31697 amit.gupta 212
    @Autowired
213
    ItelImeiActivationService itelImeiActivationService;
29488 manish 214
 
31697 amit.gupta 215
    @Autowired
216
    private PartnerTypeChangeService partnerTypeChangeService;
25598 amit.gupta 217
 
26408 amit.gupta 218
 
31697 amit.gupta 219
    @Autowired
220
    private LeadRepository leadRepository;
25927 amit.gupta 221
 
31697 amit.gupta 222
    @Autowired
223
    private AuthRepository authRepository;
25503 amit.gupta 224
 
31697 amit.gupta 225
    @Autowired
226
    private PriceDropService priceDropService;
26283 tejbeer 227
 
31697 amit.gupta 228
    @Autowired
229
    private FranchiseeVisitRepository franchiseeVisitRepository;
26790 tejbeer 230
 
31697 amit.gupta 231
    @Autowired
232
    private FranchiseeActivityRepository franchiseeActivityRepository;
26790 tejbeer 233
 
31697 amit.gupta 234
    @Autowired
235
    private HdfcPaymentRepository hdfcPaymentRepository;
26790 tejbeer 236
 
31697 amit.gupta 237
    @Autowired
238
    private CsService csService;
25846 amit.gupta 239
 
31697 amit.gupta 240
    @Autowired
241
    private SaholicInventoryService saholicInventoryService;
27208 tejbeer 242
 
31697 amit.gupta 243
    @Autowired
244
    private InsurancePolicyRepository insurancePolicyRepository;
23723 amit.gupta 245
 
31697 amit.gupta 246
    @Autowired
247
    private ToffeeService toffeeService;
25694 amit.gupta 248
 
31697 amit.gupta 249
    @Value("${oxigen.recharge.auth.key}")
250
    private String oxigenRechargeAuthKey;
23724 amit.gupta 251
 
31697 amit.gupta 252
    @Value("${oxigen.recharge.validation.url}")
253
    private String oxigenRechargeValidationUrl;
23724 amit.gupta 254
 
31697 amit.gupta 255
    @Value("${oxigen.recharge.validation.auth.key}")
256
    private String oxigenRechargeValidationAuthKey;
23724 amit.gupta 257
 
31697 amit.gupta 258
    @Value("${think.walnut.digital.recharge.transaction.mobile.url}")
259
    private String thinkWalnutDigitalRechargeTransactionMobileUrl;
23724 amit.gupta 260
 
31697 amit.gupta 261
    @Value("${think.walnut.digital.recharge.transaction.dth.url}")
262
    private String thinkWalnutDigitalRechargeTransactionDthUrl;
23724 amit.gupta 263
 
31697 amit.gupta 264
    @Value("${think.walnut.digital.recharge.enquiry.url}")
265
    private String thinkWalnutDigitalRechargeEnquiryUrl;
23724 amit.gupta 266
 
31697 amit.gupta 267
    @Value("${think.walnut.digital.recharge.balance.url}")
268
    private String thinkWalnutDigitalRechargeBalanceUrl;
23724 amit.gupta 269
 
31697 amit.gupta 270
    @Value("${think.walnut.digital.recharge.username}")
271
    private String thinkWalnutDigitalRechargeUserName;
23724 amit.gupta 272
 
31697 amit.gupta 273
    @Value("${think.walnut.digital.recharge.password}")
274
    private String thinkWalnutDigitalRechargePassword;
23724 amit.gupta 275
 
31697 amit.gupta 276
    @Value("${think.walnut.digital.recharge.auth.key}")
277
    private String thinkWalnutDigitalRechargeAuthKey;
23724 amit.gupta 278
 
31697 amit.gupta 279
    @Autowired
280
    private PurchaseRepository purchaseRepository;
23724 amit.gupta 281
 
31697 amit.gupta 282
    @Autowired
283
    private PriceDropIMEIRepository priceDropIMEIRepository;
25609 amit.gupta 284
 
31697 amit.gupta 285
    @Autowired
286
    PriceDropRepository priceDropRepository;
25609 amit.gupta 287
 
31697 amit.gupta 288
    @Autowired
289
    private PartnerTypeChangeRepository partnerTypeChangeRepository;
28368 tejbeer 290
 
31697 amit.gupta 291
    @Autowired
292
    private SchemeService schemeService;
24683 amit.gupta 293
 
31697 amit.gupta 294
    @Autowired
295
    private ServiceConfigRepository serviceConfigRepository;
29668 tejbeer 296
 
32061 amit.gupta 297
    @Autowired
298
    private RetailerBlockBrandsRepository retailerBlockBrandsRepository;
299
 
34547 vikas.jang 300
    @Autowired
301
    private LiquidationService liquidationService;
302
 
36936 vikas 303
    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"};
25609 amit.gupta 304
 
31886 tejbeer 305
    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"};
25609 amit.gupta 306
 
36936 vikas 307
    private static final String[] INDENT_TERTIARY_MAIL_LIST = new String[]{"uday.singh@smartdukaan.com", "kuldeep.kumar@smartdukaan.com", "vinay.p@smartdukaan.com", "deena.nath@smartdukaan.com", "shobhit.tandon@smartdukaan.com", "ritesh.chauhan1@smartdukaan.com"};
28709 amit.gupta 308
 
31886 tejbeer 309
    private static final String[] EMPLOYEE_ATTENDANCE_MAIL_LIST = new String[]{"sm@smartdukaan.com", "sm@smartdukaan.com"};
28790 amit.gupta 310
 
31697 amit.gupta 311
    private List<OrderStatus> orderStatusList = Arrays.asList(OrderStatus.SUBMITTED_FOR_PROCESSING);
25721 tejbeer 312
 
31697 amit.gupta 313
    @Autowired
314
    private ReporticoService reporticoService;
23724 amit.gupta 315
 
31697 amit.gupta 316
    @Autowired
317
    private PartnerInvestmentService partnerInvestmentService;
25598 amit.gupta 318
 
31697 amit.gupta 319
    @Autowired
320
    private PositionRepository positionRepository;
24337 amit.gupta 321
 
31697 amit.gupta 322
    @Autowired
323
    private FofoOrderItemRepository fofoOrderItemRepository;
25865 amit.gupta 324
 
31697 amit.gupta 325
    @Autowired
326
    private NotificationService notificationService;
24542 amit.gupta 327
 
31697 amit.gupta 328
    @Autowired
329
    private PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;
24277 amit.gupta 330
 
31697 amit.gupta 331
    @Autowired
332
    private SchemeInOutRepository schemeInOutRepository;
24241 amit.gupta 333
 
31697 amit.gupta 334
    @Autowired
335
    private RechargeTransactionRepository rechargeTransactionRepository;
23724 amit.gupta 336
 
31697 amit.gupta 337
    @Autowired
338
    private CustomerAddressRepository customerAddressRepository;
24542 amit.gupta 339
 
31697 amit.gupta 340
    @Autowired
341
    private RechargeProviderCreditWalletHistoryRepository rechargeProviderCreditWalletHistoryRepository;
23724 amit.gupta 342
 
31697 amit.gupta 343
    @Autowired
344
    private FofoLineItemRepository fofoLineItemRepository;
24590 amit.gupta 345
 
31697 amit.gupta 346
    @Autowired
347
    private FofoOrderRepository fofoOrderRepository;
24587 amit.gupta 348
 
31697 amit.gupta 349
    @Autowired
350
    private UserWalletHistoryRepository userWalletHistoryRepository;
24250 amit.gupta 351
 
31697 amit.gupta 352
    @Autowired
353
    private UserWalletRepository userWalletRepository;
24587 amit.gupta 354
 
31697 amit.gupta 355
    @Autowired
356
    private InventoryItemRepository inventoryItemRepository;
23929 amit.gupta 357
 
31697 amit.gupta 358
    @Autowired
359
    private WalletService walletService;
23724 amit.gupta 360
 
31697 amit.gupta 361
    @Autowired
362
    private ThinkWalnutDigitalRechargeProviderService thinkWalnutDigitalRechargeProviderService;
23724 amit.gupta 363
 
31697 amit.gupta 364
    @Autowired
365
    private OxigenRechargeProviderService oxigenRechargeProviderService;
23724 amit.gupta 366
 
31697 amit.gupta 367
    @Autowired
368
    private RechargeProviderRepository rechargeProviderRepository;
23724 amit.gupta 369
 
31697 amit.gupta 370
    @Autowired
371
    private ScanRecordRepository scanRecordRepository;
24242 amit.gupta 372
 
31697 amit.gupta 373
    @Autowired
374
    private DailyRechargeRepository dailyRechargeRepository;
23724 amit.gupta 375
 
31697 amit.gupta 376
    @Autowired
377
    private FofoStoreRepository fofoStoreRepository;
24177 govind 378
 
31697 amit.gupta 379
    @Value("${prod}")
380
    private boolean prod;
26945 amit.gupta 381
 
31697 amit.gupta 382
    @Autowired
383
    private StateGstRateRepository stateGstRateRepository;
23724 amit.gupta 384
 
31697 amit.gupta 385
    @Autowired
386
    private RetailerService retailerService;
23929 amit.gupta 387
 
31697 amit.gupta 388
    @Autowired
33078 ranu 389
    private BrandsRepository brandsRepository;
390
 
391
    @Autowired
31697 amit.gupta 392
    private TransactionService transactionService;
24250 amit.gupta 393
 
31697 amit.gupta 394
    @Autowired
395
    private ItemRepository itemRepository;
23929 amit.gupta 396
 
31697 amit.gupta 397
    @Autowired
398
    private OrderRepository orderRepository;
25351 tejbeer 399
 
31697 amit.gupta 400
    @Autowired
401
    private OrderService orderService;
23929 amit.gupta 402
 
31697 amit.gupta 403
    @Autowired
404
    private SchemeRepository schemeRepository;
24241 amit.gupta 405
 
31697 amit.gupta 406
    @Autowired
407
    private SchemeItemRepository schemeItemRepository;
31612 tejbeer 408
 
31697 amit.gupta 409
    @Autowired
36402 amit 410
    private JavaMailSender gmailRelaySender;
24177 govind 411
 
31697 amit.gupta 412
    @Autowired
413
    private PartnerTargetRepository partnerTargetRepository;
24002 amit.gupta 414
 
31697 amit.gupta 415
    @Autowired
416
    @Qualifier(value = "googleMailSender")
417
    private JavaMailSender googleMailSender;
23929 amit.gupta 418
 
31697 amit.gupta 419
    @Autowired
35959 amit 420
    private MailOutboxService mailOutboxService;
421
 
422
    @Autowired
31697 amit.gupta 423
    private InventoryService inventoryService;
23929 amit.gupta 424
 
31697 amit.gupta 425
    @Autowired
426
    private AddressRepository addressRepository;
24542 amit.gupta 427
 
31697 amit.gupta 428
    @Autowired
429
    private RetailerRegisteredAddressRepository retailerRegisteredAddressRepository;
24542 amit.gupta 430
 
31697 amit.gupta 431
    @Autowired
432
    private Mongo mongoClient;
24683 amit.gupta 433
 
31697 amit.gupta 434
    @Autowired
435
    private DeviceRepository deviceRepository;
25300 tejbeer 436
 
31697 amit.gupta 437
    @Autowired
438
    private PushNotificationRepository pushNotificationRepository;
25300 tejbeer 439
 
31697 amit.gupta 440
    @Autowired
441
    private NotificationCampaignRepository notificationCampaignRepository;
25300 tejbeer 442
 
31697 amit.gupta 443
    @Autowired
444
    private CurrentInventorySnapshotRepository currentInventorySnapshotRepository;
25721 tejbeer 445
 
31697 amit.gupta 446
    @Autowired
447
    private FocusedModelRepository focusedModelRepository;
25721 tejbeer 448
 
31697 amit.gupta 449
    @Autowired
450
    private UserAccountRepository userAccountRepository;
24653 govind 451
 
31697 amit.gupta 452
    @Autowired
453
    private UserRepository userUserRepository;
25721 tejbeer 454
 
31697 amit.gupta 455
    @Autowired
456
    private com.spice.profitmandi.dao.repository.dtr.UserRepository dtrUserRepository;
25927 amit.gupta 457
 
31697 amit.gupta 458
    @Autowired
459
    private UserCampaignRepository userCampaignRepository;
25721 tejbeer 460
 
31697 amit.gupta 461
    @Autowired
462
    private Gson gson;
25721 tejbeer 463
 
31697 amit.gupta 464
    @Autowired
465
    private TicketRepository ticketRepository;
26283 tejbeer 466
 
31697 amit.gupta 467
    @Autowired
468
    private RefferalRepository refferalRepository;
26790 tejbeer 469
 
31697 amit.gupta 470
    @Autowired
471
    private PartnerProblemRepository partnerProblemRepository;
28205 tejbeer 472
 
31697 amit.gupta 473
    @Autowired
474
    private PendingOrderRepository pendingOrderRepository;
28368 tejbeer 475
 
31697 amit.gupta 476
    @Autowired
477
    private PendingOrderItemRepository pendingOrderItemRepository;
28368 tejbeer 478
 
31697 amit.gupta 479
    @Value("${razorpay.account.keyId}")
480
    private String keyId;
28368 tejbeer 481
 
31697 amit.gupta 482
    @Value("${razorpay.account.keySecret}")
483
    private String keySecret;
28368 tejbeer 484
 
31697 amit.gupta 485
    @Autowired
486
    private RazorpayPaymentService razorPaymentService;
28369 tejbeer 487
 
31697 amit.gupta 488
    @Autowired
489
    private RazorPayRepository razorPayRepository;
28369 tejbeer 490
 
31697 amit.gupta 491
    @Autowired
492
    private PendingOrderService pendingOrderService;
28377 tejbeer 493
 
31697 amit.gupta 494
    @Autowired
495
    private CustomerRepository customerRepository;
28377 tejbeer 496
 
31697 amit.gupta 497
    @Autowired
498
    private RestClient restClient;
29308 tejbeer 499
 
31697 amit.gupta 500
    @Autowired
501
    private MandiiService mandiiService;
29814 tejbeer 502
 
31697 amit.gupta 503
    @Autowired
504
    CreditAccountRepository creditAccountRepository;
31604 tejbeer 505
 
31697 amit.gupta 506
    @Autowired
507
    CustomerOfferRepository customerOfferRepository;
31612 tejbeer 508
 
31697 amit.gupta 509
    @Autowired
510
    CustomerOfferItemRepository customerOfferItemRepository;
511
    @Autowired
512
    private FofoSolr fofoSolr;
23724 amit.gupta 513
 
25300 tejbeer 514
 
31697 amit.gupta 515
    private static final Logger LOGGER = LogManager.getLogger(ScheduledTasks.class);
31388 amit.gupta 516
 
34039 vikas.jang 517
    private String FCM_URL = "https://fcm.googleapis.com/v1/projects/api-project-309385327230/messages:send";
518
    private String FCM_SCOPED = "https://www.googleapis.com/auth/cloud-platform";
23724 amit.gupta 519
 
31697 amit.gupta 520
    @Autowired
521
    private TagListingRepository tagListingRepository;
33994 amit.gupta 522
    @Autowired
523
    private RunOnceTasks runOnceTasks;
23724 amit.gupta 524
 
31697 amit.gupta 525
    public void generateDailyRecharge() {
31886 tejbeer 526
        List<RechargeProviderCreditWalletHistory> allCreditHistory = rechargeProviderCreditWalletHistoryRepository.selectAll(0, 2000);
31697 amit.gupta 527
        List<RechargeProvider> rechargeProviders = rechargeProviderRepository.selectAll();
528
        rechargeProviders.stream().forEach(x -> x.setAmount(0));
23724 amit.gupta 529
 
31697 amit.gupta 530
        rechargeProviders.stream().forEach(x -> {
31886 tejbeer 531
            Map<LocalDate, List<RechargeProviderCreditWalletHistory>> dateWiseProviderCreditsMap = allCreditHistory.stream().filter(z -> z.getProviderId() == x.getId()).collect(groupingBy(x1 -> x1.getReceiveTimestamp().toLocalDate()));
23724 amit.gupta 532
 
31697 amit.gupta 533
            LOGGER.info("dateWiseProviderCreditsMap -{}", dateWiseProviderCreditsMap);
534
            LocalDate endDate = LocalDate.now().plusDays(1);
535
            float previousDayClosing = 0;
536
            LocalDate date = LocalDate.of(2018, 4, 6);
537
            while (date.isBefore(endDate)) {
31886 tejbeer 538
                List<RechargeTransaction> dateWiseRechargeTransactions = rechargeTransactionRepository.selectAllBetweenTimestamp(Arrays.asList(RechargeStatus.values()), date.atStartOfDay(), date.plusDays(1).atStartOfDay());
23724 amit.gupta 539
 
31886 tejbeer 540
                List<RechargeTransaction> successfulTransactions = dateWiseRechargeTransactions.stream().filter(y -> y.getStatus().equals(RechargeStatus.SUCCESS)).collect(Collectors.toList());
23724 amit.gupta 541
 
31697 amit.gupta 542
                float dailyAmount = 0;
543
                float totalCommission = 0;
544
                for (RechargeTransaction rechargeTransaction : successfulTransactions) {
545
                    if (rechargeTransaction.getProviderId() == x.getId()) {
546
                        dailyAmount += rechargeTransaction.getAmount();
547
                        totalCommission += rechargeTransaction.getCommission();
548
                    }
549
                }
28205 tejbeer 550
 
31697 amit.gupta 551
                List<RechargeProviderCreditWalletHistory> rechargeHistoryList = dateWiseProviderCreditsMap.get(date);
552
                float dailyWalletRecharge = 0;
553
                if (rechargeHistoryList != null) {
554
                    for (RechargeProviderCreditWalletHistory rechargeProviderCreditWalletHistory : rechargeHistoryList) {
555
                        if (rechargeProviderCreditWalletHistory.getProviderId() == x.getId()) {
556
                            dailyWalletRecharge += rechargeProviderCreditWalletHistory.getAmount();
557
                        }
558
                    }
559
                }
560
                if (dailyAmount > 0 || dailyWalletRecharge > 0) {
561
                    DailyRecharge dailyRecharge = null;
562
                    try {
563
                        dailyRecharge = dailyRechargeRepository.selectByProviderIdAndCreateDate(x.getId(), date);
564
                    } catch (Exception e) {
565
                        LOGGER.info("Could not find Recharge entry");
566
                    }
567
                    if (dailyRecharge == null) {
568
                        dailyRecharge = new DailyRecharge();
569
                        dailyRecharge.setCreateDate(date);
570
                    }
571
                    dailyRecharge.setOpeningBalance(previousDayClosing);
572
                    dailyRecharge.setProviderId(x.getId());
573
                    dailyRecharge.setWalletRechargeAmount(dailyWalletRecharge);
574
                    dailyRecharge.setTotalAmount(dailyAmount);
575
                    dailyRecharge.setTotalCommission(totalCommission);
576
                    float closingBalance = dailyRecharge.getOpeningBalance() + dailyWalletRecharge - dailyAmount;
577
                    dailyRecharge.setClosingBalance(closingBalance);
578
                    dailyRechargeRepository.persist(dailyRecharge);
579
                    x.setAmount(x.getAmount() + dailyRecharge.getClosingBalance() - dailyRecharge.getOpeningBalance());
580
                    previousDayClosing = dailyRecharge.getClosingBalance();
581
                }
582
                date = date.plusDays(1);
583
            }
584
            rechargeProviderRepository.persist(x);
585
        });
586
        LOGGER.info("finished generating daily recharge");
587
    }
24240 amit.gupta 588
 
31697 amit.gupta 589
    public void reconcileRecharge() throws Exception {
590
        LocalDateTime fromDate = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(30);
591
        LocalDateTime toDate = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS);
592
        List<RechargeStatus> nonSuccessRechargeStatuses = new ArrayList<>(Arrays.asList(RechargeStatus.values()));
593
        LOGGER.info("nonSuccessRechargeStatuses {} ", nonSuccessRechargeStatuses);
594
        nonSuccessRechargeStatuses.remove(RechargeStatus.SUCCESS);
595
        nonSuccessRechargeStatuses.remove(RechargeStatus.FAILED);
596
        RechargeCredential thinkWalnutDigitalRechargeEnquiryCredential = new RechargeCredential();
597
        thinkWalnutDigitalRechargeEnquiryCredential.setRechargeUrl(thinkWalnutDigitalRechargeEnquiryUrl);
598
        thinkWalnutDigitalRechargeEnquiryCredential.setRechargeUserName(thinkWalnutDigitalRechargeUserName);
599
        thinkWalnutDigitalRechargeEnquiryCredential.setRechargePassword(thinkWalnutDigitalRechargePassword);
600
        thinkWalnutDigitalRechargeEnquiryCredential.setRechargeAuthKey(thinkWalnutDigitalRechargeAuthKey);
601
        Map<String, RechargeStatus> requestRechargeStatusChanged = new HashMap<>();
31886 tejbeer 602
        List<RechargeTransaction> rechargeTransactions = rechargeTransactionRepository.selectAllBetweenTimestamp(nonSuccessRechargeStatuses, fromDate, toDate);
31697 amit.gupta 603
        for (RechargeTransaction rechargeTransaction : rechargeTransactions) {
604
            try {
605
                int providerId = rechargeTransaction.getProviderId();
606
                if (providerId == 1) {
31886 tejbeer 607
                    oxigenRechargeProviderService.doCheckStatusRequest(oxigenRechargeEnquiryUrl, oxigenRechargeAuthKey, rechargeTransaction);
31697 amit.gupta 608
                } else if (providerId == 2) {
31886 tejbeer 609
                    thinkWalnutDigitalRechargeProviderService.doCheckStatusRequest(thinkWalnutDigitalRechargeEnquiryCredential, rechargeTransaction);
31697 amit.gupta 610
                }
31886 tejbeer 611
                if (rechargeTransaction.getStatus().equals(RechargeStatus.SUCCESS) || rechargeTransaction.getStatus().equals(RechargeStatus.FAILED)) {
612
                    requestRechargeStatusChanged.put(rechargeTransaction.getRequestId(), rechargeTransaction.getStatus());
31697 amit.gupta 613
                }
614
            } catch (Exception e) {
615
                LOGGER.info("Could not check status for Request {}", rechargeTransaction.getRequestId());
616
            }
617
        }
618
        LOGGER.info("Reconcile recharge ran successfully");
619
    }
24241 amit.gupta 620
 
31697 amit.gupta 621
    public void processActivation() throws Exception {
622
        schemeService.processActivation();
623
    }
24241 amit.gupta 624
 
31697 amit.gupta 625
    // TemporaryMethod
626
    public void migrateInvoice() {
627
        List<FofoOrder> fofoOrders = fofoOrderRepository.selectFromSaleDate(LocalDateTime.now().minusDays(3));
628
        Map<Integer, List<FofoOrder>> partnerOrdersMap = new HashMap<>();
31886 tejbeer 629
        partnerOrdersMap = fofoOrders.stream().collect(groupingBy(FofoOrder::getFofoId, Collectors.toList()));
31697 amit.gupta 630
        for (List<FofoOrder> orderList : partnerOrdersMap.values()) {
631
            int sequence = 0;
632
            String prefix = "";
31886 tejbeer 633
            List<FofoOrder> sortedList = orderList.stream().sorted((x1, x2) -> x1.getId() - x2.getId()).collect(Collectors.toList());
31697 amit.gupta 634
            for (FofoOrder order : sortedList) {
23724 amit.gupta 635
 
31697 amit.gupta 636
                LOGGER.info("Order Id is {}, partner Id is {}", order.getId(), order.getFofoId());
637
                if (!order.getInvoiceNumber().contains("SEC")) {
638
                    sequence = Integer.parseInt(order.getInvoiceNumber().split("/")[1]);
639
                    prefix = order.getInvoiceNumber().split("/")[0];
640
                } else {
641
                    sequence += 1;
642
                    String invoiceNumber = prefix + "/" + sequence;
643
                    order.setInvoiceNumber(invoiceNumber);
644
                    fofoOrderRepository.persist(order);
645
                }
646
            }
24252 amit.gupta 647
 
31697 amit.gupta 648
        }
649
    }
28205 tejbeer 650
 
31697 amit.gupta 651
    @Autowired
652
    private ReporticoCacheTableRepository reporticoCacheTableRepository;
28205 tejbeer 653
 
31697 amit.gupta 654
    public void processSchemeOut(List<String> invoiceNumbers) throws Exception {
655
        for (String invoiceNumber : invoiceNumbers) {
656
            System.out.println("Invoice Number - " + invoiceNumber);
657
            FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
32147 amit.gupta 658
            //orderService.reverseScheme(fofoOrder);
31697 amit.gupta 659
            schemeService.processSchemeOut(fofoOrder.getId(), fofoOrder.getFofoId());
660
        }
661
    }
24271 amit.gupta 662
 
31697 amit.gupta 663
    public void processSchemeIn(List<String> invoiceNumbers) throws Exception {
664
        for (String invoiceNumber : invoiceNumbers) {
665
            System.out.println("Invoice Number - " + invoiceNumber);
666
            Purchase purchase = purchaseRepository.selectByPurchaseReference(invoiceNumber);
667
            schemeService.processSchemeIn(purchase.getId(), purchase.getFofoId());
668
        }
669
    }
24271 amit.gupta 670
 
31697 amit.gupta 671
    public void processScheme(LocalDateTime startDate, LocalDateTime endDate, boolean dryRun) throws Exception {
672
        LOGGER.info("Started execution at {}", LocalDateTime.now());
673
        System.out.println(
674
                "InventoryId\tSerialNumber\tItem Id\tScheme Id\tScheme Name\tScheme Type\tAmount Type\tDP\tTaxable\tScheme Amount\tAmount Paid");
675
        try {
676
            List<Purchase> purchases = purchaseRepository.selectAllBetweenPurchaseDate(startDate, endDate);
677
            for (Purchase purchase : purchases) {
678
                schemeService.processSchemeIn(purchase.getId(), purchase.getFofoId());
679
            }
29160 amit.gupta 680
 
31697 amit.gupta 681
            List<FofoOrder> fofoOrders = fofoOrderRepository.selectBetweenSaleDate(startDate, endDate);
682
            for (FofoOrder fofoOrder : fofoOrders) {
683
                schemeService.processSchemeOut(fofoOrder.getId(), fofoOrder.getFofoId());
684
            }
685
        } catch (Exception e) {
686
            e.printStackTrace();
687
            throw e;
688
        }
31886 tejbeer 689
        List<UserWalletHistory> uwhs = userWalletHistoryRepository.selectAllByDateType(LocalDate.now().atStartOfDay(), endDate, Arrays.asList(WalletReferenceType.SCHEME_IN, WalletReferenceType.SCHEME_OUT));
31697 amit.gupta 690
        System.out.println("Amount\tReference\tReferenceType\tTimestamp\tDescription");
691
        for (UserWalletHistory uwh : uwhs) {
31886 tejbeer 692
            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()));
31697 amit.gupta 693
        }
694
        LOGGER.info("Schemes processed successfully.");
695
        if (dryRun) {
696
            throw new Exception();
697
        }
698
    }
29160 amit.gupta 699
 
31697 amit.gupta 700
    public void processRechargeCashback() throws Throwable {
701
        LocalDateTime cashbackTime = LocalDateTime.now();
702
        int referenceId = (int) Timestamp.valueOf(cashbackTime).getTime() / 1000;
31886 tejbeer 703
        List<RechargeTransaction> pendingTransactions = rechargeTransactionRepository.getPendingCashBackRehargeTransactions();
31697 amit.gupta 704
        Map<Object, Double> totalRetailerCashbacks = pendingTransactions.stream().collect(
31724 amit.gupta 705
                groupingBy(x -> x.getRetailerId(), Collectors.summingDouble(x -> x.getCommission())));
33452 amit.gupta 706
        for (Entry<Object, Double> totalRetailerCashback : totalRetailerCashbacks.entrySet()) {
31697 amit.gupta 707
            int retailerId = (Integer) totalRetailerCashback.getKey();
708
            float amount = totalRetailerCashback.getValue().floatValue();
709
            if (Math.round(amount) > 0) {
31886 tejbeer 710
                walletService.addAmountToWallet(retailerId, referenceId, WalletReferenceType.CASHBACK, "Recharge Cashback", Math.round(amount), LocalDateTime.now());
31697 amit.gupta 711
            }
712
        }
713
        for (RechargeTransaction rt : pendingTransactions) {
714
            rt.setCashbackTimestamp(cashbackTime);
715
            rt.setCashbackReference(referenceId);
716
            rechargeTransactionRepository.persist(rt);
717
        }
718
        LOGGER.info("Cashbacks for Recharge processed Successfully");
719
    }
29160 amit.gupta 720
 
35521 amit 721
    public void rollOutUpgardedMarginsNextMonth(List<Integer> fofoIds) throws Exception {
31697 amit.gupta 722
        LocalDate startOfPreviousMonth = LocalDate.now().with(ChronoField.DAY_OF_MONTH, 1).minusMonths(1);
35521 amit 723
        List<FofoStore> stores;
35530 amit 724
        if (fofoIds == null || fofoIds.isEmpty()) {
35521 amit 725
            stores = fofoStoreRepository.selectActiveStores();
726
        } else {
727
            stores = fofoStoreRepository.selectByRetailerIds(fofoIds);
728
        }
31697 amit.gupta 729
        for (FofoStore store : stores) {
32003 amit.gupta 730
            this.rolloutMarginForStoreOnMonth(store, startOfPreviousMonth);
731
        }
732
    }
29252 amit.gupta 733
 
32003 amit.gupta 734
    public void rolloutMarginForStoreOnMonth(FofoStore store, LocalDate startOfMonth) throws ProfitMandiBusinessException {
735
        int fofoId = store.getId();
29252 amit.gupta 736
 
35531 amit 737
        // Check if there's a manual partner type change on day 1 of the month
738
        PartnerTypeChange day1Change = partnerTypeChangeRepository.selectPartnerType(fofoId, startOfMonth);
739
        if (day1Change != null && day1Change.getSource() == PartnerTypeSource.MANUAL) {
740
            LOGGER.info("Manual partner type upgrade detected for code {} to {}", store.getCode(), day1Change.getPartnerType());
741
            List<FofoOrder> fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startOfMonth.atStartOfDay(), startOfMonth.plusMonths(1).atStartOfDay(), 0, 0);
742
            for (FofoOrder fofoOrder : fofoOrders) {
743
                schemeService.processSchemeOut(fofoOrder.getId(), fofoId);
744
            }
745
            return;
746
        }
747
 
748
        // Existing logic for calculated upgrades
32003 amit.gupta 749
        PartnerType startOfPreviousMonthPartnerType = partnerTypeChangeService.getTypeOnDate(fofoId, startOfMonth);
34777 amit.gupta 750
        PartnerType todayPartnerType = partnerTypeChangeService.getTypeOnMonth(fofoId, YearMonth.from(startOfMonth));
32003 amit.gupta 751
        if (!startOfPreviousMonthPartnerType.nextPartnerTypes().contains(todayPartnerType)) {
752
            return;
753
        }
754
        if (!startOfPreviousMonthPartnerType.equals(todayPartnerType)) {
755
            LOGGER.info("Partner Type has been changed for code {} from {} to {}", store.getCode(), startOfPreviousMonthPartnerType, todayPartnerType);
756
            List<FofoOrder> fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startOfMonth.atStartOfDay(), startOfMonth.plusMonths(1).atStartOfDay(), 0, 0);
757
            for (FofoOrder fofoOrder : fofoOrders) {
758
                schemeService.processSchemeOut(fofoOrder.getId(), fofoId);
31697 amit.gupta 759
            }
760
        }
761
    }
29252 amit.gupta 762
 
32003 amit.gupta 763
 
35521 amit 764
    public void rollOutUpgardedMargins(List<Integer> fofoIds) throws Exception {
31697 amit.gupta 765
        LocalDate today = LocalDate.now();
766
        LocalDate yesterday = today.minusDays(1);
767
        int upgradedCount = 0;
35521 amit 768
        List<FofoStore> stores;
769
        if (fofoIds == null || fofoIds.isEmpty()) {
770
            stores = fofoStoreRepository.selectActiveStores();
771
        } else {
772
            stores = fofoStoreRepository.selectByRetailerIds(fofoIds);
773
        }
35461 amit 774
 
775
        // Bulk fetch partner types to avoid N+1 queries
776
        Map<Integer, PartnerType> yesterdayTypeMap = partnerTypeChangeService.getTypesForFofoIds(fofoIds, yesterday);
777
        Map<Integer, PartnerType> todayTypeMap = partnerTypeChangeService.getTypesForFofoIds(fofoIds, today);
778
 
31697 amit.gupta 779
        StringBuilder sb = new StringBuilder();
780
        for (FofoStore store : stores) {
781
            int fofoId = store.getId();
23724 amit.gupta 782
 
35461 amit 783
            PartnerType yesterdayPartnerType = yesterdayTypeMap.get(fofoId);
784
            PartnerType todayPartnerType = todayTypeMap.get(fofoId);
785
            if (yesterdayPartnerType == null || todayPartnerType == null) {
786
                continue;
787
            }
31697 amit.gupta 788
            if (!yesterdayPartnerType.nextPartnerTypes().contains(todayPartnerType)) {
789
                continue;
790
            }
791
            if (!yesterdayPartnerType.equals(todayPartnerType)) {
792
                upgradedCount++;
31886 tejbeer 793
                sb.append(String.format("Partner Type has been changed for code %s from %s to %s", store.getCode(), yesterdayPartnerType.toString(), todayPartnerType.toString()));
31697 amit.gupta 794
                sb.append("<br>");
31886 tejbeer 795
                LOGGER.info("Partner Type has been changed for code {} from {} to {}", store.getCode(), yesterdayPartnerType, todayPartnerType);
796
                List<FofoOrder> fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, yesterday.withDayOfMonth(1).atStartOfDay(), yesterday.atStartOfDay(), 0, 0);
31697 amit.gupta 797
                for (FofoOrder fofoOrder : fofoOrders) {
798
                    schemeService.processSchemeOut(fofoOrder.getId(), fofoId);
799
                }
30390 amit.gupta 800
 
31697 amit.gupta 801
            }
802
        }
803
        if (upgradedCount > 0) {
36460 ranu 804
            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");
31697 amit.gupta 805
        } else {
36460 ranu 806
            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");
31697 amit.gupta 807
        }
808
    }
30393 amit.gupta 809
 
31697 amit.gupta 810
    @Autowired
811
    private PartnerStatsService partnerStatsService;
30393 amit.gupta 812
 
35521 amit 813
// Temporary Method
30393 amit.gupta 814
 
31697 amit.gupta 815
    public void fetchParnterStats() throws Exception {
816
        Map<Integer, PartnerDetailModel> partnerStats = partnerStatsService.getAllPartnerStats();
817
        ObjectOutputStream oos = null;
818
        FileOutputStream fout = null;
819
        try {
34666 ranu 820
//            fout = new FileOutputStream("/tmp/partnerStat.tmp", false);
821
            fout = new FileOutputStream("/var/www/partner_stats/partnerStat.tmp", false);
31697 amit.gupta 822
            oos = new ObjectOutputStream(fout);
823
            oos.writeObject(partnerStats);
30637 amit.gupta 824
 
31697 amit.gupta 825
        } catch (Exception ex) {
826
            ex.printStackTrace();
827
        } finally {
828
            if (oos != null) {
829
                oos.close();
830
            }
831
        }
32421 amit.gupta 832
        ReporticoCacheTable reporticoCacheTable = reporticoCacheTableRepository.selectByTableName("partnerStat");
833
        if (reporticoCacheTable == null) {
834
            reporticoCacheTable = new ReporticoCacheTable();
835
            reporticoCacheTable.setTableName("partnerStat");
836
            reporticoCacheTable.setLastCreatedTimestamp(LocalDateTime.now());
837
            reporticoCacheTableRepository.persist(reporticoCacheTable);
31697 amit.gupta 838
        } else {
32421 amit.gupta 839
            reporticoCacheTable.setLastCreatedTimestamp(LocalDateTime.now());
31697 amit.gupta 840
        }
841
    }
31008 amit.gupta 842
 
31697 amit.gupta 843
    public void processPriceDrop() throws Exception {
31886 tejbeer 844
        List<PriceDrop> priceDrops = priceDropRepository.selectAllByDatesBetween(LocalDateTime.now(), LocalDateTime.now().minusYears(1));
31697 amit.gupta 845
        for (PriceDrop priceDrop : priceDrops) {
846
            if (priceDrop.getDropAmount() > 0) {
847
                priceDropService.processPriceDrop(priceDrop.getId(), true);
848
            }
849
        }
850
    }
31008 amit.gupta 851
 
31697 amit.gupta 852
    @Autowired
853
    CreditNoteService creditNoteService;
25598 amit.gupta 854
 
36993 amit 855
    public void sendCreditNote(YearMonth yearMonth, boolean dryRun) throws Exception {
856
        LOGGER.info("Running SendCreditNote for {} (dryRun={})", yearMonth.toString(), dryRun);
857
        creditNoteService.issueMonthlyMarginsCN(yearMonth, dryRun);
31697 amit.gupta 858
    }
25598 amit.gupta 859
 
36220 amit 860
    public void genDNs(YearMonth yearMonth) throws Exception {
861
        LOGGER.info("Running genDNs for {}", yearMonth.toString());
862
        creditNoteService.generateDebitNotesForCancelled(yearMonth);
863
    }
864
 
36503 amit 865
    public void genDNsForCNs(List<String> cnNumbers) throws Exception {
866
        LOGGER.info("Running genDNs for {} explicit CNs", cnNumbers.size());
867
        creditNoteService.generateDebitNotesForCancelled(cnNumbers);
868
    }
869
 
31918 amit.gupta 870
    @Autowired
871
    BrandAgeingLimitRepository brandAgeingLimitRepository;
872
 
873
    @Autowired
874
    AgeingService ageingService;
875
 
33928 ranu 876
    @Autowired
877
    RbmTargetService rbmTargetService;
878
 
31918 amit.gupta 879
    public void sendMailForAgeingAlert() throws Exception {
880
        //brandAgeingLimitRepository.selectAll();
881
        Map<String, AgeingModel> ageingModelMap = ageingService.getAllAgeingForSecondary();
882
 
883
        System.out.println(ageingModelMap.size());
884
        List<PartnerAgeingModel> partnerAgeingModels = ageingService.getAllAgeingForTertiary();
885
 
886
 
33452 amit.gupta 887
        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()));
31918 amit.gupta 888
 
33452 amit.gupta 889
        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()));
890
        Attachment attachment1 = new Attachment("secondary-alert.csv", new ByteArrayResource(byteArrayOutputStream.toByteArray()));
891
        Attachment attachment2 = new Attachment("tertiary-alert.csv", new ByteArrayResource(byteArrayOutputStream2.toByteArray()));
31918 amit.gupta 892
 
893
        String mailSubject = "Stock ageing Alert";
35959 amit 894
        mailOutboxService.queueMailWithAttachmentsViaGoogle(new String[]{"deena.nath@smartdukaan.com"}, null, mailSubject, "PFA", "ScheduledTasks.sendMailForAgeingAlert", attachment1, attachment2);
31918 amit.gupta 895
    }
896
 
32690 amit.gupta 897
 
33357 amit.gupta 898
    public void processDeductions() {
899
        sidbiService.processDeductions();
900
    }
901
 
35521 amit 902
    public void resetHardLimit() throws ProfitMandiBusinessException {
33904 amit.gupta 903
        sdCreditService.resetHardLimit();
904
    }
905
 
35021 amit 906
    public void testInvoiceFormat() throws ProfitMandiBusinessException {
907
        InvoicePdfModel invoicePdfModel = orderService.getInvoicePdfModel(560280);
908
        //System.out.println(InvoiceFormatter.buildInvoiceLines(invoicePdfModel, InvoiceFormatter.WIDTH_80MM));
909
    }
910
 
35326 amit 911
    public void sendTrialExpiry() {
912
        List<FofoStore> stores = fofoStoreRepository.selectAllTrial();
35521 amit 913
        List<FofoStore> twoDaysToExpiry = stores.stream().filter(x -> x.getTrialEnd().minusDays(2).equals(LocalDate.now())).collect(Collectors.toList());
35326 amit 914
 
35521 amit 915
        List<FofoStore> fiveDaysToExpiry = stores.stream().filter(x -> x.getTrialEnd().minusDays(5).equals(LocalDate.now())).collect(Collectors.toList());
916
        List<FofoStore> expiredToday = stores.stream().filter(x -> x.getTrialEnd().equals(LocalDate.now())).collect(Collectors.toList());
917
        List<FofoStore> expired = stores.stream().filter(x -> x.getTrialEnd().isAfter(LocalDate.now())).collect(Collectors.toList());
35326 amit 918
    }
919
 
34710 amit.gupta 920
    /*public void processCashDiscount() throws ProfitMandiBusinessException {
921
        System.out.println("processing cash discount");
922
        List<Loan> loansSettledYesterday = loanRepository.selectLoansSettledOn(LocalDate.now().minusDays(1));
923
        loansSettledYesterday.addAll(loanRepository.selectLoansSettledOn(LocalDate.now()));
924
        Map<Integer, List<Loan>> partnerSettledLoans = loansSettledYesterday.stream().collect(Collectors.groupingBy(x -> x.getFofoId()));
925
        for (Entry<Integer, List<Loan>> partnerLoans : partnerSettledLoans.entrySet()) {
926
            List<Loan> fullCdLoans = partnerLoans.getValue().stream().filter(x -> x.getInvoiceNumber() != null && x.getDays() <= ProfitMandiConstants.LOAN_PARTIAL_CREDIT_DAYS).collect(toList());
927
            List<Loan> partialCdLoans = partnerLoans.getValue().stream().filter(x -> x.getInvoiceNumber() != null && x.getDays() > ProfitMandiConstants.LOAN_PARTIAL_CREDIT_DAYS &&
928
                    x.getDays() <= ProfitMandiConstants.LOAN_FULL_CREDIT_DAYS).collect(toList());
929
            //List<Loan> noCdLoans = loanRepository.selectLoansDueByDays()
930
            //
931
            for (Loan fullCdLoan : fullCdLoans) {
932
                LOGGER.info("FullCdLoan - {}", fullCdLoan);
933
                schemeService.processFullCD(fullCdLoan.getInvoiceNumber());
934
            }
935
 
936
            for (Loan partialCdLoan : partialCdLoans) {
937
                schemeService.processPartialCD(partialCdLoan.getInvoiceNumber());
938
            }
939
 
940
            *//*for (Loan noCdLoan : noCdLoans) {
941
                schemeService.processNoCD(noCdLoan.getInvoiceNumber());
942
            }*//*
943
        }
944
 
945
    }*/
946
 
31697 amit.gupta 947
    private class SaleRoles {
25598 amit.gupta 948
 
31697 amit.gupta 949
        private List<String> l1;
950
        private List<String> l2;
25598 amit.gupta 951
 
31697 amit.gupta 952
        public SaleRoles() {
953
            l1 = new ArrayList<>();
954
            l2 = new ArrayList<>();
955
        }
25598 amit.gupta 956
 
31697 amit.gupta 957
        public List<String> getL1() {
958
            return l1;
959
        }
25598 amit.gupta 960
 
31697 amit.gupta 961
        public List<String> getL2() {
962
            return l2;
963
        }
26945 amit.gupta 964
 
31697 amit.gupta 965
    }
26945 amit.gupta 966
 
31697 amit.gupta 967
    private class FofoReportingModel {
968
        private String code;
969
        private int fofoId;
970
        private String businessName;
971
        private String territoryManager;
972
        private String regionalManager;
973
        private String businessManager;
26945 amit.gupta 974
 
31697 amit.gupta 975
        public String getCode() {
976
            return code;
977
        }
26945 amit.gupta 978
 
31697 amit.gupta 979
        public void setCode(String code) {
980
            this.code = code;
981
        }
26945 amit.gupta 982
 
31697 amit.gupta 983
        public String getBusinessName() {
984
            return businessName;
985
        }
26945 amit.gupta 986
 
31697 amit.gupta 987
        public void setBusinessName(String businessName) {
988
            this.businessName = businessName;
989
        }
26945 amit.gupta 990
 
31697 amit.gupta 991
        public String getTerritoryManager() {
992
            return territoryManager;
993
        }
26945 amit.gupta 994
 
31697 amit.gupta 995
        public void setTerritoryManager(String territoryManager) {
996
            this.territoryManager = territoryManager;
997
        }
26945 amit.gupta 998
 
31697 amit.gupta 999
        public String getRegionalManager() {
1000
            return regionalManager;
1001
        }
26945 amit.gupta 1002
 
31697 amit.gupta 1003
        public void setRegionalManager(String regionalManager) {
1004
            this.regionalManager = regionalManager;
1005
        }
26945 amit.gupta 1006
 
31697 amit.gupta 1007
        private ScheduledTasks getOuterType() {
1008
            return ScheduledTasks.this;
1009
        }
26945 amit.gupta 1010
 
31697 amit.gupta 1011
        @Override
1012
        public String toString() {
31886 tejbeer 1013
            return "FofoReportingModel{" + "code='" + code + '\'' + ", fofoId=" + fofoId + ", businessName='" + businessName + '\'' + ", territoryManager='" + territoryManager + '\'' + ", regionalManager='" + regionalManager + '\'' + ", businessManager='" + businessManager + '\'' + '}';
31697 amit.gupta 1014
        }
26945 amit.gupta 1015
 
31697 amit.gupta 1016
        @Override
1017
        public boolean equals(Object o) {
1018
            if (this == o) return true;
1019
            if (o == null || getClass() != o.getClass()) return false;
1020
            FofoReportingModel that = (FofoReportingModel) o;
1021
            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);
1022
        }
26945 amit.gupta 1023
 
31697 amit.gupta 1024
        @Override
1025
        public int hashCode() {
1026
            return Objects.hash(code, fofoId, businessName, territoryManager, regionalManager, businessManager);
1027
        }
26945 amit.gupta 1028
 
31697 amit.gupta 1029
        public String getBusinessManager() {
1030
            return businessManager;
1031
        }
26945 amit.gupta 1032
 
31697 amit.gupta 1033
        public void setBusinessManager(String businessManager) {
1034
            this.businessManager = businessManager;
1035
        }
25351 tejbeer 1036
 
31697 amit.gupta 1037
        public int getFofoId() {
1038
            return fofoId;
1039
        }
25598 amit.gupta 1040
 
31697 amit.gupta 1041
        public void setFofoId(int fofoId) {
1042
            this.fofoId = fofoId;
1043
        }
25598 amit.gupta 1044
 
31697 amit.gupta 1045
    }
26945 amit.gupta 1046
 
31697 amit.gupta 1047
    @Autowired
1048
    WarehouseInventoryItemRepository warehouseInventoryItemRepository;
26945 amit.gupta 1049
 
31746 amit.gupta 1050
    @Autowired
1051
    OfferService offerService;
1052
 
1053
    @Autowired
1054
    PurchaseReturnItemRepository purchaseReturnItemRepository;
1055
 
31918 amit.gupta 1056
    @Autowired
1057
    BrandRegionMappingRepository brandRegionMappingRepository;
1058
 
32161 tejbeer 1059
    @Autowired
1060
    StandAlone standAlone;
32214 jai.hind 1061
    @Autowired
1062
    ItelImeiActivationNewService itelImeiActivationNewService;
32350 amit.gupta 1063
 
1064
    public void checkItelImeiActivationNew(LocalDate date, Integer day) throws Exception {
32063 amit.gupta 1065
        try {
32223 amit.gupta 1066
            itelImeiActivationNewService.checkItelImeiActivationNew(date, day);
32063 amit.gupta 1067
        } catch (Throwable e) {
1068
            throw new Exception(e);
1069
        }
32223 amit.gupta 1070
    }
32062 amit.gupta 1071
 
32511 amit.gupta 1072
    @Autowired
1073
    PurchaseReturnService purchaseReturnService;
1074
 
32682 amit.gupta 1075
    @Autowired
1076
    JavaMailSender javaMailSender;
1077
 
32795 amit.gupta 1078
    @Autowired
1079
    OfferPayoutRepository offerPayoutRepository;
1080
 
1081
    @Autowired
1082
    OfferRepository offerRepository;
1083
 
32817 amit.gupta 1084
    @Autowired
1085
    BluedartAuthService bluedartAuthService;
1086
    @Autowired
1087
    BluedartService bluedartService;
1088
 
1089
    @Autowired
1090
    TransactionRelatedTasks transactionRelatedTasks;
1091
 
32872 amit.gupta 1092
    @Autowired
1093
    PsiSmartService psiSmartService;
32948 amit.gupta 1094
 
32961 amit.gupta 1095
    private void migrateValentine() throws ProfitMandiBusinessException {
1096
        List<FofoOrder> fofoOrders = fofoOrderRepository.selectBetweenSaleDate(LocalDate.now().atStartOfDay(), LocalDateTime.now());
1097
        for (FofoOrder fofoOrder : fofoOrders) {
1098
            orderService.processScratchOffer(fofoOrder);
1099
        }
1100
    }
33051 amit.gupta 1101
 
32990 amit.gupta 1102
    @Autowired
1103
    InvoiceService invoiceService;
1104
 
33384 amit.gupta 1105
    @Autowired
1106
    WarehouseService warehouseService;
1107
 
33452 amit.gupta 1108
    @Autowired
1109
    GenericRepository genericRepository;
1110
 
1111
    @Autowired
1112
    PriceCircularService priceCircularService;
1113
 
34611 ranu 1114
    /*@Autowired
1115
    RedisCacheManager redisFortnightlyCacheManage;*/
33638 amit.gupta 1116
 
1117
    @Autowired
1118
    GstProAuthService gstProAuthService;
33664 amit.gupta 1119
 
33817 amit.gupta 1120
    @Autowired
1121
    GstProService gstProService;
1122
 
1123
    @Autowired
1124
    WarehouseProviderRepository warehouseProviderRepository;
33928 ranu 1125
 
34160 tejus.loha 1126
    @Autowired
1127
    LoiFormRepository loiFormRepository;
1128
    @Autowired
1129
    PartnerOnBoardingPanelRepository partnerOnBoardingPanelRepository;
1130
    @Autowired
1131
    StoreTimelineTatService storeTimelineTatService;
1132
    @Autowired
1133
    PartnerDealerRepository partnerDealerRepository;
33664 amit.gupta 1134
 
34275 tejus.loha 1135
    @Autowired
1136
    PurSaleService purSaleService;
1137
 
34502 amit.gupta 1138
    @Autowired
1139
    CatalogRepository catalogRepository;
1140
 
35021 amit 1141
    @Autowired
1142
    AbmReportSender abmReportSender;
34510 amit.gupta 1143
 
35021 amit 1144
    public void sendOverDueReport() {
1145
        List<Loan> loans = loanRepository.selectAllActiveLoan();
35521 amit 1146
        Map<Integer, List<Loan>> partnerLoansMap = loans.stream().filter(x -> x.isOverdue()).collect(Collectors.groupingBy(x -> x.getFofoId()));
35021 amit 1147
        //sdCreditService.getDueDateCrossLoan()
35521 amit 1148
        partnerLoansMap.entrySet().stream().forEach(x -> {
34858 amit 1149
 
35021 amit 1150
            x.getKey();
1151
            x.getValue().size();
1152
        });
34858 amit 1153
 
35021 amit 1154
    }
1155
 
35295 amit 1156
    @Autowired
1157
    OnBoardingRelatedSchelduleTask onBoardingRelatedSchelduleTask;
1158
 
1159
    @Autowired
1160
    Migrations migrations;
1161
 
1162
    /*@Autowired
1163
    BenowService benowService;*/
1164
 
1165
    @Autowired
1166
    TrialFormRepository trialFormRepository;
1167
 
1168
    @Autowired
1169
    CreditBlockedExceptionPartnersRepository creditBlockedExceptionPartnersRepository;
1170
 
1171
    @Autowired
1172
    SDCreditService sdCreditService;
1173
 
35393 amit 1174
    @Autowired
35666 vikas 1175
    PinelabsAffordabilityService pinelabsAffordabilityService;
35393 amit 1176
 
1177
    @Autowired
35666 vikas 1178
    PinelabsAuthService pinelabsAuthService;
35521 amit 1179
 
35666 vikas 1180
    @Autowired
1181
    PinelabsOfferCacheService pinelabsOfferCacheService;
1182
 
35788 vikas 1183
    @Autowired
1184
    ShopifyProductSyncService shopifyProductSyncService;
1185
 
35666 vikas 1186
    /**
1187
     * Caches pinelabs offers for all active items in Redis.
1188
     * Call this method from your cron job to pre-populate the cache.
1189
     */
1190
    public void cachePinelabsOffers() {
1191
        pinelabsOfferCacheService.cacheAllItemOffers();
1192
    }
1193
 
35788 vikas 1194
    public void syncProductsToShopifyByWarehouseId(int warehouseId) throws Exception {
1195
        shopifyProductSyncService.syncByWarehouse(warehouseId);
1196
    }
1197
 
1198
    public void syncInventoryToShopifyByWarehouseId(int warehouseId) throws Exception {
1199
        shopifyProductSyncService.syncInventory(warehouseId);
1200
    }
1201
 
35393 amit 1202
    public void testAffordability() {
1203
        Money orderAmount = new Money("1000000", "INR");
1204
        Money discountAmount = new Money("0", "INR");
1205
        List<ProductDetails> productDetails = Arrays.asList(new ProductDetails(orderAmount, discountAmount, "Alpha_2"));
1206
        OfferDiscoveryRequest offerDiscoveryRequest = new com.spice.profitmandi.service.integrations.pinelabs.dto.OfferDiscoveryRequest(orderAmount, productDetails, new AffordabilityIssuer("12345678"));
1207
        OfferDiscoveryResponse offerDiscoveryResponse = pinelabsAffordabilityService.discoverOffers(offerDiscoveryRequest);
1208
        System.out.println(offerDiscoveryResponse);
1209
    }
35521 amit 1210
 
35021 amit 1211
    public void test() throws Exception {
35393 amit 1212
 
36034 amit 1213
        //System.out.println(pinelabsAuthService.getAccessToken());
1214
        //testAffordability();
36652 amit 1215
        //mailOutboxService.processPendingMails();
35295 amit 1216
        //System.out.println(trialFormRepository.selectByEmailOrMobile("9990381568"));
1217
        /*CreditBlockedExceptionPartner creditBlockedExceptionPartner = creditBlockedExceptionPartnersRepository.select(175139430);
1218
        System.out.println(creditBlockedExceptionPartner);*/
35330 amit 1219
        //this.updatePartnerLimit(175139595);
36652 amit 1220
        this.fixStuckLimitBlocks(9999);
36430 amit 1221
        //this.regenerateDCInvoices();
36042 amit 1222
        //this.releaseBlockedLimit();
35326 amit 1223
        //sdCreditService.resetHardLimit();
35295 amit 1224
        //migrations.migrateSerialInvoiceMap();
35151 amit 1225
        //runOnceTasks.checkRewardsEligibility();
35295 amit 1226
        //hybridEncryptor.getJwt();
1227
        /*System.out.printf("Date|Transaction Id|Serial Number|Sale Amount|Swipe Payout|Discount Payout%n");
1228
        for(int i=0;i<10;i++){
1229
            benowService.parseBenowTransaction(LocalDate.now().minusDays(i));
1230
        }*/
1231
        //onBoardingRelatedSchelduleTask.onboardingEventDelays();
35177 amit 1232
        //runOnceTasks.migrateLimit();866009067657118
1233
        //TODO -- Sales Return Pending
1234
        //runOnceTasks.moveSaleReturnScanToDoa("866009067657118");
35295 amit 1235
        //runOnceTasks.sendCreditExposureReport();
35177 amit 1236
        //runOnceTasks.moveDoaScanToSaleReturn("868770072438608");
35150 vikas 1237
        //runOnceTasks.purchasePolicy();
35105 vikas 1238
        //purSaleService.moreThen10DaysEgedStockReport();
35102 amit 1239
        //System.out.println(schemeService.testRedis(1, 2L));
1240
        //System.out.println(schemeService.testRedis(1, null));
35177 amit 1241
        // abmReportSender.sendAbmSmartCartReport();
1242
        //this.sendOverDueReport();
35053 amit 1243
        /*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);
35021 amit 1244
        for (Integer orderId : orderIds) {
1245
            System.out.println("Refund Started - " + orderId);
1246
            orderRepository.refundOrder(orderId, "vinay.p", "Long awaited cancellation", OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY);
1247
            System.out.println("Refund Ended");
35053 amit 1248
        }*/
1249
        //System.out.println(warehouseSupplierInvoiceRepository.selectWarehouseItemAgeing(LocalDateTime.now().minusDays(10), LocalDateTime.now(), null, 0, null));
35102 amit 1250
        /*Offer offer = offerRepository.selectById(6820);
1251
        offerService.sendWhatsapp(offer, Arrays.asList(175140233),"https://images.smartdukaan.com/uploads/campaigns/image2025-09-24/offer-6820.png");*/
1252
        /*List<String> invoices = Arrays.asList("NSDLNOI16527","NSDLNOI16366", "NSDLNOI16394", "NSDLNOI16460");
35056 amit 1253
        List<Loan> loans = new ArrayList<>();
1254
        for (String invoice : invoices) {
1255
            loans.add(loanRepository.selectLoanByInvoice(invoice));
1256
        }
1257
        loans.stream().sorted(Comparator.comparing(x->x.getCreatedOn())).forEach(x-> {
1258
            try {
1259
                sdCreditService.settleLoan(x);
1260
            } catch (ProfitMandiBusinessException e) {
1261
                throw new RuntimeException(e);
1262
            }
35102 amit 1263
        });*/
36460 ranu 1264
        //Utils.sendMailWithAttachments(googleMailSender, new String[]{"amit.gupta@smartdukaan.com"}, null, "DTDC AWb", "PFA");*/
33452 amit.gupta 1265
    }
1266
 
36039 amit 1267
    private void regenerateDCInvoices() {
1268
        List<String> dcInvoiceNumbers = Arrays.asList(
1269
                "DCNSUPDL5", "DCNSUPDL4", "DCNSLCK2", "DCNSUPDL3",
1270
                "DCNSUPDL2", "DCNSUPDL1", "DCNSLCK1");
1271
        for (String invoiceNumber : dcInvoiceNumbers) {
1272
            try {
1273
                List<Order> orders = orderRepository.selectByInvoiceNumber(invoiceNumber);
1274
                if (!orders.isEmpty()) {
36046 amit 1275
                    invoiceService.saveInvoice(orders);
1276
                    System.out.println("Regenerated DC: " + invoiceNumber);
36039 amit 1277
                }
1278
            } catch (Exception e) {
1279
                System.out.println("Failed to regenerate DC: " + invoiceNumber + " - " + e.getMessage());
1280
            }
1281
        }
1282
    }
1283
 
35330 amit 1284
    private void releaseBlockedLimit() throws ProfitMandiBusinessException {
1285
        List<Loan> blockedLoans = loanRepository.selectAllBlockedLoans();
1286
        for (Loan blockedLoan : blockedLoans) {
1287
            LoanTransaction loanTransaction = loanTransactionRepository.selectByLoanId(blockedLoan.getId());
1288
            int transactionId = loanTransaction.getTransactionId();
1289
            List<UserWalletHistory> userWalletHistory = walletService.getAllByReference(blockedLoan.getFofoId(), transactionId, WalletReferenceType.PURCHASE);
35521 amit 1290
            int amount = userWalletHistory.get(userWalletHistory.size() - 1).getAmount();
35330 amit 1291
            int loanAmount = blockedLoan.getIntialAmount().intValue();
35521 amit 1292
            if (loanAmount > -amount) {
1293
                sdCreditService.settleBlockedLoan(transactionId, loanAmount + amount);
35330 amit 1294
            }
1295
 
1296
 
1297
        }
1298
    }
1299
 
34731 amit.gupta 1300
    @Autowired
1301
    LoanTransactionRepository loanTransactionRepository;
1302
 
1303
    private void fixBlockedCredit() throws ProfitMandiBusinessException {
35877 amit 1304
        List<Loan> unsettledBlockedLoans = loanRepository.selectAllBlockedLoans();
34731 amit.gupta 1305
        //unsettledBlockedLoans = unsettledBlockedLoans.stream().filter(x -> x.getId() == 52310).collect(toList());
1306
        for (Loan unsettledBlockedLoan : unsettledBlockedLoans) {
1307
            LoanTransaction loanTransaction = loanTransactionRepository.selectByLoanId(unsettledBlockedLoan.getId());
1308
            if (loanTransaction == null) {
1309
                System.out.println("Cant find Transaction Id for Loan - " + unsettledBlockedLoan.getId() + "-- Created On ->" + unsettledBlockedLoan.getCreatedOn());
1310
                continue;
1311
            }
1312
            List<Order> processedOrders = orderRepository.selectAllByTransactionId(loanTransaction.getTransactionId()).stream()
1313
                    .filter(x -> !x.getStatus().equals(OrderStatus.SUBMITTED_FOR_PROCESSING)).collect(toList());
1314
            List<OrderStatus> processedOrderIds = processedOrders.stream().map(x -> x.getStatus()).collect(Collectors.toList());
1315
            System.out.println("processedOrderIds " + processedOrderIds);
1316
            //if(unsettledBlockedLoan !=null) continue;
1317
            double limitToRelease = processedOrders.stream().collect(Collectors.summingDouble(x -> x.getWalletAmount()));
1318
            sdCreditService.releaseBlockedLimit(unsettledBlockedLoan, limitToRelease);
1319
 
1320
 
1321
        }
1322
    }
1323
 
36430 amit 1324
    private void fixStuckLimitBlocks(int maxFixes) {
36654 amit 1325
        int[] stuckIds = {100908, 100909, 102018, 104843, 105119, 105613, 105758, 105766, 105999};
36430 amit 1326
 
36654 amit 1327
        List<Loan> stuckLoans = new ArrayList<>();
1328
        for (int id : stuckIds) {
1329
            Loan loan = loanRepository.selectByLoanId(id);
1330
            if (loan != null && loan.isLimitBlock() && loan.getSettledOn() == null && loan.getPendingAmount().doubleValue() > 0) {
1331
                stuckLoans.add(loan);
1332
            }
1333
        }
36430 amit 1334
 
36654 amit 1335
        System.out.println("Found " + stuckLoans.size() + " stuck limit blocks to fix");
36430 amit 1336
        System.out.println("Max fixes this run: " + maxFixes);
1337
 
1338
        int fixed = 0, skipped = 0, failed = 0;
1339
        for (Loan blockedLoan : stuckLoans) {
1340
            if (fixed >= maxFixes) {
1341
                System.out.println("Reached max fixes limit (" + maxFixes + "), stopping.");
1342
                break;
1343
            }
1344
 
1345
            try {
1346
                LoanTransaction loanTransaction = loanTransactionRepository.selectByLoanId(blockedLoan.getId());
1347
                if (loanTransaction == null) {
1348
                    System.out.println("SKIP loan " + blockedLoan.getId() + " - no LoanTransaction found");
1349
                    skipped++;
1350
                    continue;
1351
                }
1352
                int transactionId = loanTransaction.getTransactionId();
1353
                List<Order> billedOrders = orderRepository.selectAllByTransactionId(transactionId).stream()
1354
                        .filter(o -> o.getBillingTimestamp() != null && o.getRefundTimestamp() == null)
1355
                        .collect(toList());
1356
 
1357
                Map<String, List<Order>> byInvoice = billedOrders.stream()
1358
                        .filter(o -> o.getInvoiceNumber() != null)
1359
                        .collect(Collectors.groupingBy(Order::getInvoiceNumber));
1360
 
1361
                for (Map.Entry<String, List<Order>> entry : byInvoice.entrySet()) {
1362
                    String invoiceNumber = entry.getKey();
1363
                    double invoiceAmount = entry.getValue().stream().mapToDouble(Order::getWalletAmount).sum();
1364
 
1365
                    Loan existingLoan = loanRepository.selectLoanByInvoice(invoiceNumber);
1366
                    if (existingLoan != null) {
1367
                        System.out.println("SKIP loan " + blockedLoan.getId() + " invoice " + invoiceNumber + " - loan already exists (id=" + existingLoan.getId() + ")");
1368
                        continue;
1369
                    }
1370
 
1371
                    System.out.println("FIX loan " + blockedLoan.getId() + " fofo " + blockedLoan.getFofoId() + " txn " + transactionId + " invoice " + invoiceNumber + " invoiceAmt " + invoiceAmount + " pending " + blockedLoan.getPendingAmount());
1372
                    sdCreditService.createLoanForBilling(transactionId, invoiceAmount, invoiceNumber);
1373
                    fixed++;
1374
                }
36654 amit 1375
 
1376
                blockedLoan = loanRepository.selectByLoanId(blockedLoan.getId());
1377
                if (blockedLoan.getPendingAmount().doubleValue() > 0) {
1378
                    System.out.println("RELEASE remaining limit " + blockedLoan.getId() + " fofo " + blockedLoan.getFofoId() + " pending " + blockedLoan.getPendingAmount());
1379
                    sdCreditService.releaseBlockedLimit(blockedLoan, blockedLoan.getPendingAmount().doubleValue());
1380
                    fixed++;
1381
                }
36430 amit 1382
            } catch (Exception e) {
1383
                System.out.println("FAIL loan " + blockedLoan.getId() + " fofo " + blockedLoan.getFofoId() + " - " + e.getMessage());
1384
                e.printStackTrace();
1385
                failed++;
1386
            }
1387
        }
1388
        System.out.println("Done. fixed=" + fixed + " skipped=" + skipped + " failed=" + failed);
1389
    }
1390
 
1391
    private void compensateAlreadyFixedLoans() {
1392
        int[] alreadyFixedLoanIds = {106138, 106139, 106140, 106141, 106142, 106143, 106144, 106145, 106146, 106147};
1393
        System.out.println("Compensating " + alreadyFixedLoanIds.length + " already-fixed loans");
1394
 
1395
        int done = 0, failed = 0;
36472 amit 1396
 
36430 amit 1397
        for (int loanId : alreadyFixedLoanIds) {
1398
            try {
1399
                Loan loan = loanRepository.selectByLoanId(loanId);
1400
                if (loan == null) {
1401
                    System.out.println("SKIP compensate loan " + loanId + " - not found");
1402
                    continue;
1403
                }
1404
                double compensateAmount = loan.getIntialAmount().doubleValue();
1405
                String compensateDesc = "Compensating double credit - forced loan " + loan.getId() + " against invoice " + loan.getInvoiceNumber();
1406
                walletService.consumeAmountFromWallet(loan.getFofoId(), loan.getId(),
1407
                        WalletReferenceType.CREDIT_UTILIZED, compensateDesc, (float) compensateAmount, LocalDateTime.now());
1408
                System.out.println("COMPENSATE fofo " + loan.getFofoId() + " loan " + loan.getId() + " amount -" + compensateAmount);
1409
 
1410
                String forcedLoanReason = "Forced loan against invoice " + loan.getInvoiceNumber() + " (limit fix)";
1411
                Loan forcedLoan = sdCreditService.createLoan(loan.getFofoId(), compensateAmount, loan.getFreeDays(), forcedLoanReason);
1412
                System.out.println("FORCED LOAN fofo " + loan.getFofoId() + " loan " + forcedLoan.getId() + " amount " + compensateAmount + " freeDays " + loan.getFreeDays());
1413
                done++;
1414
            } catch (Exception e) {
1415
                System.out.println("FAIL compensate loan " + loanId + " - " + e.getMessage());
1416
                e.printStackTrace();
1417
                failed++;
1418
            }
1419
        }
1420
        System.out.println("Compensate done. done=" + done + " failed=" + failed);
1421
    }
1422
 
34710 amit.gupta 1423
    public static byte[] toByteArray(InputStream input) throws IOException {
1424
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
1425
        int nRead;
1426
        byte[] data = new byte[16384];
1427
        while ((nRead = input.read(data, 0, data.length)) != -1) {
1428
            buffer.write(data, 0, nRead);
1429
        }
1430
        return buffer.toByteArray();
1431
    }
1432
 
34547 vikas.jang 1433
    private void whatsappTest() throws Exception {
34603 ranu 1434
        //liquidationService.processBids(ProfitMandiConstants.BID_CRON_ENUM.TODAY);
35959 amit 1435
        mailOutboxService.queueMailViaGoogle(new String[]{"ranu.rajput@smartdukaan.com"}, null, "Test Mail", "Mail is working", "ScheduledTasks.whatsappTest");
34532 amit.gupta 1436
    }
1437
 
34510 amit.gupta 1438
    private void debitLoanAmountFromWallet() {
1439
        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);
1440
        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));
1441
        l1.addAll(Arrays.asList());
1442
    }
1443
 
33452 amit.gupta 1444
    public void test4() throws Exception {
1445
        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);
1446
        for (Integer offerId : offerIds) {
1447
            Offer fromOffer = offerRepository.selectById(offerId);
1448
            CreateOfferRequest createOfferRequest = offerService.getCreateOfferRequest(fromOffer);
1449
            System.out.println("Processing offer Id " + fromOffer);
1450
            offerService.processActivationtOffer(createOfferRequest);
1451
        }
34160 tejus.loha 1452
 
33433 amit.gupta 1453
        this.processSidbiDeductions();
32817 amit.gupta 1454
    }
1455
 
1456
    public void test3() throws Exception {
1457
        List<Long> payoutIds = Arrays.asList();
32795 amit.gupta 1458
        List<OfferPayout> offerPayouts = offerPayoutRepository.selectAllByIds(payoutIds);
33452 amit.gupta 1459
        Map<Integer, List<OfferPayout>> offerPayoutMap = offerPayouts.stream().collect(groupingBy(x -> (int) x.getOfferId()));
1460
        for (Entry<Integer, List<OfferPayout>> offerPayoutEntry : offerPayoutMap.entrySet()) {
32795 amit.gupta 1461
            int offerId = offerPayoutEntry.getKey();
1462
            List<OfferPayout> offerPayoutList = offerPayoutEntry.getValue();
33452 amit.gupta 1463
            Map<Integer, List<OfferPayout>> partnerOfferPayoutMap = offerPayoutList.stream().collect(groupingBy(x -> (int) x.getFofoId()));
32795 amit.gupta 1464
            for (Entry<Integer, List<OfferPayout>> partnerOfferPayoutEntry : partnerOfferPayoutMap.entrySet()) {
1465
                int fofoId = partnerOfferPayoutEntry.getKey();
1466
                List<OfferPayout> partnerPayouts = partnerOfferPayoutEntry.getValue();
1467
                float amount = 0;
1468
                for (OfferPayout offerPayout : partnerPayouts) {
1469
                    amount += offerPayout.getAmount();
1470
                    offerPayout.setStatus(SchemePayoutStatus.REJECTED);
1471
                    offerPayout.setRejectTimestamp(LocalDateTime.now());
1472
                }
1473
                walletService.rollbackAmountFromWallet(fofoId, amount, offerId,
1474
                        WalletReferenceType.ADDITIONAL_SCHEME, "Imeis returned - " + partnerPayouts.size() + "pc(s)", LocalDateTime.now());
1475
            }
1476
        }
1477
    }
1478
 
33316 amit.gupta 1479
    public void test1() throws Exception {
32690 amit.gupta 1480
        System.out.println("Hello from test");
32724 amit.gupta 1481
        //this.calculateInterestAccured();
32690 amit.gupta 1482
        //sendMailOfHtmlFormat(javaMailSender, new String[]{"amit.gupta@smartdukaan.com"}, "hello", null, "Hello");
32698 amit.gupta 1483
        //priceDropService.rejectPriceDropsOfApprovedImeis();
32511 amit.gupta 1484
        //Create return
32600 amit.gupta 1485
        //this.updatePartnerLimit();
32607 ranu 1486
        //creditNoteService.sendCnMails(YearMonth.now().minusMonths(2));
32690 amit.gupta 1487
        //orderService.createMissingScratchOffers();
33315 amit.gupta 1488
        LocalDateTime debitNoteDate = LocalDate.of(2024, Month.APRIL, 30).atStartOfDay();
32698 amit.gupta 1489
        Map<Integer, Set<String>> fofoIdImeiReturnMap = new LinkedHashMap<>();
33355 amit.gupta 1490
        /*fofoIdImeiReturnMap.put(175139690,	new HashSet<>(Arrays.asList("862054078463472","863862077158219","866202075810858","866202077654494","866335072023651","866518078002718")));
33315 amit.gupta 1491
        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")));
1492
        fofoIdImeiReturnMap.put(175139603,	new HashSet<>(Arrays.asList("350886063151961","356412387787135","357594162824701","357594162874771","860600078193972","863862077025350","863862077875796","863967075815072","866335073794995","866335074287874","869116067546048")));
1493
        fofoIdImeiReturnMap.put(175139657,	new HashSet<>(Arrays.asList("350933415734746","354324787135850","354324788766356","354990352512960","354990352580181","358142881241184","866611064207332","869116067600464")));
1494
        fofoIdImeiReturnMap.put(175139223,	new HashSet<>(Arrays.asList("350210770983048","350210771169027","350210771179844","350210771180784","863975067090596","866611060326797","868565075758196","869452074016992","869452074609515","869452074609556","869452074976674","869452074978654")));
1495
        fofoIdImeiReturnMap.put(175139557,	new HashSet<>(Arrays.asList("861977073551795","861977073552678","861977074486819","862046062571245","862046067278226","862046067734921","862046067756866","864468070394741","864468071225506","864468071668341","864468073604740","864468074854625","866993074734475")));
1496
        fofoIdImeiReturnMap.put(175139079,	new HashSet<>(Arrays.asList("862046068861921","862282079169299","865388071283496","866335072007753","866335073946256","866518073601712","866518077425993","866518078760471","868938062675394","868938062690799","868938064895552")));
1497
        fofoIdImeiReturnMap.put(175139711,	new HashSet<>(Arrays.asList("861753065266498","861888066009099","864468073703369","866993071640154","869116062800465")));
1498
        fofoIdImeiReturnMap.put(175139488,	new HashSet<>(Arrays.asList("862054076866114","862054076866650","866335071879079","866335077875998","866335077876095","866518078758939","868938062692878")));
1499
        fofoIdImeiReturnMap.put(175138934,	new HashSet<>(Arrays.asList("862054072810231","862054072823150","862054076867674","862054078659590","863862075768456","863862077158193","863975064472490","863975064473233","865388071160033","865610079408035","866335072117370","866335073899471","866335074306153","866335075664477","868938062669876","868938062677895","868938062685997")));
1500
        fofoIdImeiReturnMap.put(4149607	 ,   new HashSet<>(Arrays.asList("864468073415741","864468075548523","864468075549927","864468079499426","866657074106022","868938062686656","868938062696978","868938062699352","868938064895198","868938066363799")));
1501
        fofoIdImeiReturnMap.put(175139138,	new HashSet<>(Arrays.asList("862286066217631","864259076533691","864468073358842","864487061610014","864487061675918","866083066080028","866518078760950","866518078768979","866657075343848","868544061108518","868544061138432","869116065510848","869116065519781","869452074116891","869452074972939")));
1502
        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")));
1503
        fofoIdImeiReturnMap.put(175139731,	new HashSet<>(Arrays.asList("860600079214413","861753063502217","861753065084172","861753065084636","863975064472094","863975064473076","863975064477218","864468074456462","865883068726994","866657074641481","866657078016946","868938062699832","868938062700754")));
1504
        fofoIdImeiReturnMap.put(175138958,	new HashSet<>(Arrays.asList("863862075766393","864179064784108","866202075811732","866202076252654","866202078005571","868544060277439")));
1505
        fofoIdImeiReturnMap.put(175139612,	new HashSet<>(Arrays.asList("864468073474946","864468073477808","864468075031082","864468075280689","864468075745723","864468079481747","864468079483123","866657074538125","866657074538141","866657074573106","867467071856465","867467071875465","867467071891223","867467071913845","867467072729125","867467072760088")));
1506
        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")));
1507
        fofoIdImeiReturnMap.put(175139245,	new HashSet<>(Arrays.asList("354324787133962","354324787569397","354324787602750","863816078139719","863816078448318","866335070534139")));
1508
        fofoIdImeiReturnMap.put(175139324,	new HashSet<>(Arrays.asList("863718060410316","863862075060755","865610074109257","866518078844457","866518079735159")));
1509
        fofoIdImeiReturnMap.put(175139576,	new HashSet<>(Arrays.asList("354324789013261","861128071288044","862736064686138","863718062236859","863816074642674","863816074646691","864259078939631","867467071870367","867467072760625","868565073047048")));
1510
        fofoIdImeiReturnMap.put(175139150,	new HashSet<>(Arrays.asList("860492060436217","861977073052257","862054073026738","862054073052056","863862077158938","866993074147710","867907071407074","868938060257450","868956064835055")));
1511
        fofoIdImeiReturnMap.put(175139463,	new HashSet<>(Arrays.asList("862181066909552","863816077757719","863816078448516","864214068977273","866335070447936","866335071699212","866335071699592","866335071700291")));
1512
        fofoIdImeiReturnMap.put(175139722,	new HashSet<>(Arrays.asList("358250293364682","358250294683627","358250295102007","861858064421273","861888066009537","864214068983198","864259078491112","864259078787733","865883068445694","866335072878930","866518078371014","868492068014968","868565072254660","868565073401468","868565073465661")));
1513
        fofoIdImeiReturnMap.put(168311083,	new HashSet<>(Arrays.asList("863718064506176","864468070873488","865883068175572","866335071204435","866335072093738","866518077064313","866657077386209","866657077862282","868938061427359")));
1514
        fofoIdImeiReturnMap.put(175139691,	new HashSet<>(Arrays.asList("863718061338714","863718061339258")));
1515
        fofoIdImeiReturnMap.put(175139395,	new HashSet<>(Arrays.asList("860492060436910","861220079009850","862054077288730","863511068660374","863718060300574","863718060617936","866335072874111","869452070894897")));
1516
        fofoIdImeiReturnMap.put(175139621,	new HashSet<>(Arrays.asList("351240553452191","351240553483527","351240553502920","354990353485570","860492062979750","860492062980998","864214068585274","864214068784398","864214068795378","864214068946534","864214068946757","864214068982075","868938061418754","868938061427391","868938062623139")));
1517
        fofoIdImeiReturnMap.put(175139638,	new HashSet<>(Arrays.asList("863862077159191","866518078780438","866518079750471","868428060238049","868938061532836","868938062619517")));
1518
        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")));
1519
        fofoIdImeiReturnMap.put(175139513,	new HashSet<>(Arrays.asList("861977073670355","863718060618439","864468075204986","868024064295935","868024065473754","868024065567811","868024065763972","868956063947893")));
1520
        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")));
1521
        fofoIdImeiReturnMap.put(175139359,	new HashSet<>(Arrays.asList("358250293060942","358250293061387","863718063044252","863862077160991","866335072536793","866335072536975","866335072537130","866335072726691","866335072726733","866335073628532","866335073925250","866335073925292","866335073926233","866335075267156")));
1522
        fofoIdImeiReturnMap.put(175139397,	new HashSet<>(Arrays.asList("861977073659010","863511069721050","864468071611101","864468074432844","864468074435284")));
1523
        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")));
1524
        fofoIdImeiReturnMap.put(175139460,	new HashSet<>(Arrays.asList("860492061918494","862054079983072","862054079983171","866335070533032","866518078995119","866518079014993","868938060095017")));
1525
        fofoIdImeiReturnMap.put(175139585,	new HashSet<>(Arrays.asList("358250293614706","358250293614904","358250294602908","358250294603120","358250295002181","861977074487718","863718061173699","863816078050254","865883068445777","866335070453439","866335070526812","866335071204351","866518078640293","869116067596803")));
1526
        fofoIdImeiReturnMap.put(175139726,	new HashSet<>(Arrays.asList("861858064489411","863718063927654","864468073702221","864468073928784","864468074193149","865883068445819","866657078378742","866657078498904","867949078179850","867949078180494","868544060023197")));
1527
        fofoIdImeiReturnMap.put(175139532,	new HashSet<>(Arrays.asList("863718060615096","863718060615617","863718060727537","863816077797897","866335073405139","868565072217287","868565072264560","868956065132510")));
1528
        fofoIdImeiReturnMap.put(175139462,	new HashSet<>(Arrays.asList("865610074119819","865610074120536","866335072878658","866335072882098","866335073617030")));
1529
        fofoIdImeiReturnMap.put(175139259,	new HashSet<>(Arrays.asList("350210771180644","355300593052348","860492061918213","861858064422651","864259078402572","864259078924310","866335070769719","866335071700556","866335071742558","866657073553208","867949078178530","867949078692472","868024065518616","868024065619091","869116067492540")));
1530
        fofoIdImeiReturnMap.put(175139344,	new HashSet<>(Arrays.asList("350115571135781","354990352587723","358250293362843","358250293363148","862736064732510","865610070849617","865610070851290","866518078899998","868938062623378","868956065234613")));
1531
        fofoIdImeiReturnMap.put(175139602,	new HashSet<>(Arrays.asList("861128070090482","868565072242160","868565072243044","868565072261004","868565073051644")));
1532
        fofoIdImeiReturnMap.put(175139605,	new HashSet<>(Arrays.asList("861515075217922","861515076369466","863816074206397","863816075080072","864259078661755","864468075627368","867467071860541","868565072177903","868565073075726","868565073401625","868938060248012","868938066709652","869452074088611","869452074609234")));
1533
        fofoIdImeiReturnMap.put(175139640,	new HashSet<>(Arrays.asList("358250293363429","358250293363684","861753065277792","863511069733998","864214068943713","864259078496574","864259078518773","864487060042870","864487060050352","865883069366170","866518079782391","867949078692639","867949078692852","868273068551617","868938066464571","869452073150115")));
1534
        fofoIdImeiReturnMap.put(175139346,	new HashSet<>(Arrays.asList("356494471614953","860600076022215","861765072074616","861977070097412","864468074885181","864468076046105","865610073263139","865883065558994","866335075002538","866657079093605","867907070983216")));
1535
        fofoIdImeiReturnMap.put(175139489,	new HashSet<>(Arrays.asList("354324789015209","354324789081797","861515075189824","861515075575501","861977070268997","864468072790144","864468072983921","864468075233225","866657077951960","869452071082492","869452071982378","869452074617070")));
1536
        fofoIdImeiReturnMap.put(175139508,	new HashSet<>(Arrays.asList("861515075367024","864468072781283","864468074453386","864468075200448","864468076050669","866083062293849")));
1537
        fofoIdImeiReturnMap.put(175139716,	new HashSet<>(Arrays.asList("350832440575209","358250295571425","860600076019492","861753063494373","861753063501151","864468073696100","864468074855689","865883065542311","865883067956030","866202075825450","866202077663297","866335073632591","866657078023769")));
1538
        fofoIdImeiReturnMap.put(175139727,	new HashSet<>(Arrays.asList("355300592353325","355300593005387","861765072344258","862046060196128","864468073908604","864468073910121","864468073911269","867437074118411","868024064300099","868024065464977","868024065468218","869116065414389")));
1539
        fofoIdImeiReturnMap.put(175139521,	new HashSet<>(Arrays.asList("860600071402594","860600071416719","861888064397496","861977073658616","864468070509587","864468073866406","866335074999056","866657077949642","866657078406964","866993072229072","867437070891698")));
1540
        fofoIdImeiReturnMap.put(175139523,	new HashSet<>(Arrays.asList("354324785409950","354324788632830","354990352587939","358250295736085","358250295805187","358311601935629","863967076359575","866657074163502","867907070986318","869452071963378","869452074611750")));
1541
        fofoIdImeiReturnMap.put(175139697,	new HashSet<>(Arrays.asList("862282078030112","862282078867117","863975067709930","863975068443810","864468072828860","864468073705786","864468075276489","864468075277685","865610073830739","866335073264577","866518079802116","866657074518903","866657077949980","868565073058664","868938060985639","869116065613949")));
1542
        fofoIdImeiReturnMap.put(175139622,	new HashSet<>(Arrays.asList("358250293381926","358250293382304","358250293382601","358250294076046","358250294078109","358250294078463","358250294602064","358250294602429","358250294603062","358250294603203")));
1543
        fofoIdImeiReturnMap.put(175139699,	new HashSet<>(Arrays.asList("863718064441317","865610074942897","866202077653173","866202077653553","866335072262671","866335073632211","866335074805519")));
1544
        fofoIdImeiReturnMap.put(175139741,	new HashSet<>(Arrays.asList("861515071386101","861515074123402","861515074124186","861977073047752","861977073658574","864468075082804","864468076049869","865883065542139","865883067957111","866518070599679","866518079800672","866657078018587","866657078270162","866657079236220")));
1545
        fofoIdImeiReturnMap.put(175139114,	new HashSet<>(Arrays.asList("861888066708856","861977074487692","866335070051217","866335070517274","866993074145631")));
1546
        fofoIdImeiReturnMap.put(175139531,	new HashSet<>(Arrays.asList("863816077976194","863816079685710","866335070997336","866335074729354","866335075514698")));
1547
        fofoIdImeiReturnMap.put(175139386,	new HashSet<>(Arrays.asList("350210771192805","358250295053846","860388068563434","863862077333374","864468075193221","864562077193757","864718076084310","866202077464092","866202077742190","866518077001513","868565079682020","868956065252516")));
1548
        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")));
1549
        fofoIdImeiReturnMap.put(175139306,	new HashSet<>(Arrays.asList("863718064547394","864718076075516","864718076083478","866202077463631","866202077470057")));
1550
        fofoIdImeiReturnMap.put(175139733,	new HashSet<>(Arrays.asList("350210771180008","861515071845668","861888067164877","866335070489094","866518076378276","868565072242269")));
1551
        fofoIdImeiReturnMap.put(175138824,	new HashSet<>(Arrays.asList("862054078573478","863862074697490","863862075442375","864468074485545","866335070216315","866657078016169","866657078449402","869116065542247")));
1552
        fofoIdImeiReturnMap.put(175139511,	new HashSet<>(Arrays.asList("862054075642557","862054075643530","862054076379357","862054077978934","863816078158016","868938062108974")));
1553
        fofoIdImeiReturnMap.put(175139701,	new HashSet<>(Arrays.asList("863862078258331","866611061131790")));
1554
        fofoIdImeiReturnMap.put(175139552,	new HashSet<>(Arrays.asList("861753065084958","866202075814439","866202075825633","866202075864194","866202076138754","866202076252811","866202077646870","866202077651094","866202077653876","866202077659956","866202077660293","866202077663339","866202078006397","866202078006611","866202078008914","866657078023280")));
1555
        fofoIdImeiReturnMap.put(175139499,	new HashSet<>(Arrays.asList("351115165467359","351115166905951","355358277809813","355358277814052","356049795822532","358250290682060","863862075504950","864468073944906","864468076048721","866657079234365")));
1556
        fofoIdImeiReturnMap.put(175139630,	new HashSet<>(Arrays.asList("357349229650288","358250290499184","358250294552947","358250294590301","860946078570556","860946078571059","861977073552215","861977073657790","861977073657832","861977073658731","861977074660850","862054075627517","862054075632756","862054075642979","862054076374879","863967071220830")));
1557
        fofoIdImeiReturnMap.put(175139720,	new HashSet<>(Arrays.asList("865388072300075","866335073071691","866335073073697","866335073390398")));
1558
        fofoIdImeiReturnMap.put(175138854,	new HashSet<>(Arrays.asList("50115570082950","351688420279827","351688420575703","354324788647382","357594162666201","359333606194530","863862075760198")));
1559
        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")));
1560
        fofoIdImeiReturnMap.put(175139610,	new HashSet<>(Arrays.asList("862736063981738","863718063044617","866335072870176","866335072870598")));
1561
        fofoIdImeiReturnMap.put(175139366,	new HashSet<>(Arrays.asList("354324783144864","354324788632608","354889661849990","354990353239423","863967070558271","864718076129396","866657077789543","866657078285368","866657078508066","869116060977828","869116061054429","869116061208546")));
1562
        fofoIdImeiReturnMap.put(175139412,	new HashSet<>(Arrays.asList("351115165488595","351115165491318","351115165491359","351115165491458","351115165492332","355358278026573","355358278081610","861888063460717","861977073052018","863816078633919","865883069477035","866335074538870","866993071639594")));
1563
        fofoIdImeiReturnMap.put(175139504,	new HashSet<>(Arrays.asList("862054072660792","862054075971873","862054076312374","862054077948630","863816075363171","863862075442334","864718075894230","868938062122017","868938065268932","869452071940632","869452073034897","869452073158233","869452073158498","869452074159735")));
1564
        fofoIdImeiReturnMap.put(175139201,	new HashSet<>(Arrays.asList("863718061956671","863862075497734","863862075596915","864718076078510","864718076134834","866335070211639","866611060437032","866611061133812")));
1565
        fofoIdImeiReturnMap.put(175139362,	new HashSet<>(Arrays.asList("350201087545646","350201087547048","350201087547709","350201087548764","350201087597043","350201087597167","350201087597464","350201087597787","350201087598165","350201087600789","863718062929271","865883069477191","865883069477530","866335071174133","866518078023870","866518078243072","868938061053494")));
33355 amit.gupta 1566
        fofoIdImeiReturnMap.put(175139661,	new HashSet<>(Arrays.asList("860946077691031","861977074661155","862054073218855","866335070523694","867940069973476","868938062656477")));*/
33452 amit.gupta 1567
        fofoIdImeiReturnMap.put(175139556, new HashSet<>(Arrays.asList("863718063534013", "866335072895173", "866335073390810")));
1568
        fofoIdImeiReturnMap.put(175139721, new HashSet<>(Arrays.asList("358250294549067", "865883067508138", "866993072210619")));
33355 amit.gupta 1569
        /*fofoIdImeiReturnMap.put(175139455,	new HashSet<>(Arrays.asList("358293804087913","866518078020694","866518078021650","866518078243676","866518078571936")));
33315 amit.gupta 1570
        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")));
1571
        fofoIdImeiReturnMap.put(175139559,	new HashSet<>(Arrays.asList("863718069016890","863816078879256","864468075283881","866335073245436","866335073403571","866657074268327","868024065473853","868956065899993","869452070362895","869452074030274")));
1572
        fofoIdImeiReturnMap.put(175139575,	new HashSet<>(Arrays.asList("354324786659199","860388067452035","861220078009919","863816078878134","863862075841154","865388070857498","867907071407116")));
33355 amit.gupta 1573
        fofoIdImeiReturnMap.put(175139686,	new HashSet<>(Arrays.asList("866657078019106","866657078032869")));*/
33315 amit.gupta 1574
 
33355 amit.gupta 1575
        //this.processOrdersToRebill(fofoIdImeiReturnMap, debitNoteDate);
1576
        purchaseReturnService.fixReturns(fofoIdImeiReturnMap, debitNoteDate);
32513 amit.gupta 1577
 
32698 amit.gupta 1578
    }
1579
 
1580
 
33315 amit.gupta 1581
    private void processOrdersToRebill(Map<Integer, Set<String>> fofoIdImeiReturnMap, LocalDateTime debitNoteDate) throws Exception {
32698 amit.gupta 1582
 
1583
 
1584
        for (Entry<Integer, Set<String>> fofoIdImeiReturnEntry : fofoIdImeiReturnMap.entrySet()) {
32511 amit.gupta 1585
            int fofoId = fofoIdImeiReturnEntry.getKey();
1586
            Set<String> imeis = fofoIdImeiReturnEntry.getValue();
1587
            List<InventoryItem> inventoryItems = inventoryItemRepository.selectByFofoIdSerialNumbers(fofoId, imeis, true);
1588
            for (InventoryItem inventoryItem : inventoryItems) {
1589
                //inventoryItem.getId();
1590
                purchaseReturnService.returnInventoryItem(fofoId, true, inventoryItem.getId(), ReturnType.GOOD);
1591
                //Approve return
1592
                PurchaseReturnItem purchaseReturnItem = purchaseReturnItemRepository.selectByInventoryItemId(inventoryItem.getId());
1593
                purchaseReturnItem.setStatus(PurchaseReturnStatus.APPROVED);
1594
                purchaseReturnItem.setApproveTimestamp(LocalDateTime.now());
1595
            }
1596
            Map<Purchase, List<InventoryItem>> purchaseInventoryItemsMap = purchaseReturnService.getPurchaseMapForApprovedReturns(fofoId);
1597
            int walletAmount = walletService.getWalletAmount(fofoId);
1598
            List<DebitNote> debitNotes = purchaseReturnService.generateDebitNotes(purchaseInventoryItemsMap);
1599
            int walletDiff = walletAmount - walletService.getWalletAmount(fofoId);
1600
            if (walletDiff > 0) {
1601
                int reference = walletService.getManualReference(WalletReferenceType.OTHERS);
32514 amit.gupta 1602
                walletService.addAmountToWallet(fofoId, reference, WalletReferenceType.ADVANCE_AMOUNT, "Sytematically added for internal PO", (float) walletDiff + 5000, LocalDateTime.now());
32511 amit.gupta 1603
            }
32698 amit.gupta 1604
            List<CartItem> cartItems = new ArrayList<>();
32511 amit.gupta 1605
            for (DebitNote debitNote : debitNotes) {
33315 amit.gupta 1606
                debitNote.setCreateTimestamp(debitNoteDate);
32511 amit.gupta 1607
                //Try to refund amount per debit note
32698 amit.gupta 1608
                cartItems.addAll(this.refundDnAmount(debitNote));
32511 amit.gupta 1609
            }
32698 amit.gupta 1610
            //If order created
33452 amit.gupta 1611
            Map<Integer, List<CartItem>> warehouseCartItemsMap = cartItems.stream().collect(groupingBy(x -> x.getWarehouseId()));
1612
            for (Entry<Integer, List<CartItem>> warehouseCartItemsEntry : warehouseCartItemsMap.entrySet()) {
32223 amit.gupta 1613
 
32698 amit.gupta 1614
                List<CartItem> warehouseCartItems = warehouseCartItemsEntry.getValue();
1615
 
1616
                List<CartItem> mergedCartItems = warehouseCartItems.stream()
1617
                        .collect(Collectors.collectingAndThen(
33452 amit.gupta 1618
                                groupingBy(x -> x.getItemId(), Collectors.collectingAndThen(
32724 amit.gupta 1619
                                        Collectors.reducing((a, b) -> {
32698 amit.gupta 1620
                                            a.setQuantity(a.getQuantity() + b.getQuantity());
1621
                                            return a;
1622
                                        }), Optional::get)),
1623
                                m -> new ArrayList<>(m.values())));
1624
 
32724 amit.gupta 1625
                double walletTotalAmount = mergedCartItems.stream().mapToDouble(x -> x.getQuantity() * x.getSellingPrice()).sum();
32698 amit.gupta 1626
 
1627
                com.spice.profitmandi.dao.entity.user.User user = userRepository.selectById(fofoId);
1628
                cartService.clearCart(user.getActiveCartId());
1629
                cartService.addItemsToCart(user.getActiveCartId(), mergedCartItems);
1630
 
1631
                UserCart userCart = new UserCart();
1632
                userCart.setCartId(user.getActiveCartId());
1633
                userCart.setUserId(user.getId());
1634
 
1635
                int transactionId = transactionService.createTransactionInternally(userCart, walletTotalAmount, warehouseCartItemsEntry.getKey());
1636
                commonPaymentService.payThroughWallet(transactionId);
34352 amit.gupta 1637
                transactionService.processTransaction(transactionId, 0);
32698 amit.gupta 1638
            }
1639
        }
31697 amit.gupta 1640
    }
32048 tejbeer 1641
 
32384 amit.gupta 1642
    @Autowired
32511 amit.gupta 1643
    CartService cartService;
1644
    @Autowired
1645
    UserRepository userRepository;
1646
 
1647
    @Autowired
1648
    WarehouseScanRepository warehouseScanRepository;
1649
 
1650
    @Autowired
1651
    WarehouseInventoryService warehouseInventoryService;
1652
 
1653
    @Autowired
1654
    CommonPaymentService commonPaymentService;
1655
 
32533 amit.gupta 1656
    @Autowired
1657
    LineItemImeisRepository lineItemImeisRepository;
1658
 
32698 amit.gupta 1659
 
32511 amit.gupta 1660
    //Also create order
32698 amit.gupta 1661
    private List<CartItem> refundDnAmount(DebitNote debitNote) throws ProfitMandiBusinessException {
32511 amit.gupta 1662
        List<Integer> inventoryItemIds = purchaseReturnItemRepository.selectAllByDebitNoteId(debitNote.getId()).stream().map(x -> x.getInventoryItemId()).collect(Collectors.toList());
33452 amit.gupta 1663
        Map<Integer, Long> inventoryItemCountMap = inventoryItemIds.stream().collect(groupingBy(x -> x, Collectors.counting()));
32511 amit.gupta 1664
        List<InventoryItem> inventoryItems = inventoryItemRepository.selectAllByIds(new ArrayList<>(inventoryItemCountMap.keySet()));
1665
        Purchase purchase = purchaseRepository.selectById(inventoryItems.get(0).getPurchaseId());
1666
        String invoice = purchase.getPurchaseReference();
1667
        List<Order> orders = orderRepository.selectByInvoiceNumber(invoice);
1668
        Set<Integer> orderIds = orders.stream().map(x -> x.getId()).collect(Collectors.toSet());
1669
        Order order = orders.get(0);
1670
        float totalAmount = 0;
1671
        int totalQty = 0;
1672
        Map<Integer, CartItem> itemIdCartItemMap = new HashMap<>();
1673
 
35447 amit 1674
        // Batch fetch all TagListings by itemIds to avoid N+1 queries
1675
        Set<Integer> allItemIds = inventoryItems.stream()
1676
                .map(InventoryItem::getItemId)
1677
                .collect(Collectors.toSet());
1678
        List<TagListing> allTagListings = tagListingRepository.selectByItemIdsAndTagIds(allItemIds, null);
1679
        Map<Integer, TagListing> itemIdTagListingMap = allTagListings.stream()
1680
                .collect(Collectors.toMap(TagListing::getItemId, t -> t, (u, v) -> u));
1681
 
32511 amit.gupta 1682
        List<CartItem> cartItems = new ArrayList<>();
1683
        for (InventoryItem inventoryItem : inventoryItems) {
35447 amit 1684
            TagListing tagListing = itemIdTagListingMap.get(inventoryItem.getItemId());
32511 amit.gupta 1685
            long quantity = inventoryItemCountMap.get(inventoryItem.getId());
1686
            totalAmount += inventoryItem.getUnitPrice() * quantity;
1687
            totalQty += quantity;
1688
            if (!itemIdCartItemMap.containsKey(inventoryItem.getItemId())) {
1689
                CartItem cartItem = new CartItem();
1690
                cartItem.setItemId(inventoryItem.getItemId());
1691
                cartItem.setSellingPrice(tagListing.getSellingPrice());
32698 amit.gupta 1692
                cartItem.setWarehouseId(order.getWarehouseId());
32511 amit.gupta 1693
                cartItems.add(cartItem);
1694
                itemIdCartItemMap.put(inventoryItem.getItemId(), cartItem);
1695
            }
1696
            CartItem cartItem = itemIdCartItemMap.get(inventoryItem.getItemId());
1697
            cartItem.setQuantity((int) quantity + cartItem.getQuantity());
1698
        }
1699
        String rollbackDescription = String.format("Refunded against DN %s, %d pc(s)", debitNote.getDebitNoteNumber(), totalQty);
1700
        walletService.addAmountToWallet(debitNote.getFofoId(), order.getTransactionId(), WalletReferenceType.PURCHASE, rollbackDescription, totalAmount, LocalDateTime.now());
1701
        //Before creating order lets try to in the stock
1702
 
1703
        //All scans pertaining to specific Invoices
1704
        List<WarehouseScan> warehouseScans = warehouseScanRepository.selectAllByOrderIds(new ArrayList<>(orderIds));
32698 amit.gupta 1705
        Map<Integer, Integer> inventoryItemIdOrderIdMap = new HashMap<>();
1706
        try {
1707
            inventoryItemIdOrderIdMap = warehouseScans.stream().collect(Collectors.toMap(x -> x.getInventoryItemId(), x -> x.getQuantity()));
32724 amit.gupta 1708
        } catch (Exception e) {
32698 amit.gupta 1709
            LOGGER.info("Could not process for fofoId - {}, {}", debitNote.getFofoId(), warehouseScans);
1710
        }
32511 amit.gupta 1711
        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)))
1712
                .map(x -> x.getInventoryItemId()).collect(Collectors.toList());
1713
        List<WarehouseInventoryItem> warehouseInventoryItems = warehouseInventoryItemRepository.selectAllByIds(warehouseInventoryItemIds);
1714
 
1715
        Map<String, WarehouseInventoryItem> serialNumberWarehouseInventoryItemMap = warehouseInventoryItems.stream().filter(x -> StringUtils.isNotBlank(x.getSerialNumber())).collect(Collectors.toMap(x -> x.getSerialNumber(), x -> x));
1716
 
1717
        for (InventoryItem inventoryItem : inventoryItems) {
1718
            if (StringUtils.isBlank(inventoryItem.getSerialNumber())) {
1719
                //As of now this should be happening as  dn are specifically for serialized devices
1720
                /*int returnQty = inventoryItemCountMap.get(inventoryItem.getId()).intValue();
1721
                List<WarehouseInventoryItem> warehouseInventoryItemList = itemIdWarehouseInventoryItemsMap.get(inventoryItem.getItemId());
1722
                warehouseInventoryService.returnNonSerializedQty(warehouseInventoryItem)*/
1723
            } else if (StringUtils.isNotBlank(inventoryItem.getSerialNumber())) {
1724
                String serialNumber = inventoryItem.getSerialNumber();
1725
                WarehouseInventoryItem warehouseInventoryItem = serialNumberWarehouseInventoryItemMap.get(serialNumber);
1726
                warehouseInventoryItem.setLastScanType(in.shop2020.warehouse.ScanType.SALE_RET);
1727
                warehouseInventoryService.addQuantity(warehouseInventoryItem.getId(), 1);
1728
                WarehouseScan warehouseScan = new WarehouseScan();
1729
                warehouseScan.setInventoryItemId(warehouseInventoryItem.getId());
1730
                warehouseScan.setQuantity(1);
1731
                warehouseScan.setOrderId(inventoryItemIdOrderIdMap.get(warehouseInventoryItem.getItemId()));
1732
                warehouseScan.setScannedAt(LocalDateTime.now());
1733
                warehouseScan.setType(in.shop2020.warehouse.ScanType.SALE_RET);
1734
                warehouseScanRepository.persist(warehouseScan);
1735
 
1736
            }
1737
        }
1738
 
1739
        //Create Order as well
32724 amit.gupta 1740
        return cartItems;
32698 amit.gupta 1741
    }
32511 amit.gupta 1742
 
32698 amit.gupta 1743
    void addToCartAndCreateOrder() {
32511 amit.gupta 1744
 
1745
    }
1746
 
1747
    @Autowired
32384 amit.gupta 1748
    WarehouseDebitNoteRepository warehouseDebitNoteRepository;
1749
    @Autowired
1750
    WarehouseDebitNoteLineRepository warehouseDebitNoteLineRepository;
1751
 
1752
    @Autowired
1753
    WarehouseInvoiceItemRepository warehouseInvoiceItemRepository;
1754
    @Autowired
1755
    WarehouseSupplierInvoiceRepository warehouseSupplierInvoiceRepository;
1756
 
1757
    @Autowired
1758
    PurchaseOrderService purchaseOrderService;
1759
 
32482 amit.gupta 1760
    @Autowired
1761
    VendorCatalogPricingLogRepository vendorCatalogPricingLogRepository;
32384 amit.gupta 1762
 
32214 jai.hind 1763
//    private void checkItelImeiActivationNew(LocalDate now, int i) {
1764
//    }
1765
 
32169 amit.gupta 1766
    @Autowired
1767
    SessionFactory sessionFactory;
1768
 
1769
 
31697 amit.gupta 1770
    public void sendMailForSamsungRebilling() throws Exception {
1771
        List<BilledImeiModel> samsungModels = warehouseInventoryItemRepository.findByBillingDateBrand(LocalDate.now(), "Samsung");
1772
        LOGGER.info("SamsungModels {}", samsungModels);
1773
        samsungModels = samsungModels.stream().sorted(Comparator.comparing(x -> x.getPcmDate() == null ? -1 : 1)).collect(Collectors.toList());
1774
        if (samsungModels.size() > 0) {
1775
            List<String> headers = Arrays.asList("Partner Id", "Code", "Name", "City", "Brand", "Model Name", "Model Number", "Color", "Serial Number", "Remarks");
1776
            List<List<?>> rows = new ArrayList<>();
1777
            for (BilledImeiModel billedImeiModel : samsungModels) {
31886 tejbeer 1778
                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");
31697 amit.gupta 1779
                rows.add(row);
1780
            }
1781
            ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, rows);
1782
            String[] sendToArray = new String[]{"kamini.sharma@smartdukaan.com", "praveen.sharma@smartdukaan.com"};
1783
            String fileName = "Imeis need Rebilling -" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv";
36460 ranu 1784
            Utils.sendMailWithAttachment(googleMailSender, sendToArray, new String[]{"tarun.verma@smartdukaan.com"}, "Samsung Rebilling IMEI Summary", "PFA", fileName, new ByteArrayResource(baos.toByteArray()));
31697 amit.gupta 1785
        }
1786
    }
24002 amit.gupta 1787
 
31697 amit.gupta 1788
    public void sendPartnerInvestmentDetails(List<String> sendTo) throws Exception {
1789
        LocalDate yesterDay = LocalDate.now().minusDays(1);
1790
        List<FofoStore> fofoStores = fofoStoreRepository.selectActiveStores();
31886 tejbeer 1791
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(fofoStores.stream().map(x -> x.getId()).collect(Collectors.toList()));
25312 amit.gupta 1792
 
32169 amit.gupta 1793
        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");
31697 amit.gupta 1794
        List<List<?>> rows = new ArrayList<>();
1795
        Map<Integer, List<?>> partnerRowsMap = new HashMap<>();
25598 amit.gupta 1796
 
31697 amit.gupta 1797
        Map<Integer, FofoReportingModel> partnerIdSalesHeaderMap = this.getPartnerIdSalesHeaders();
25312 amit.gupta 1798
 
31886 tejbeer 1799
        Map<Integer, Integer> shortDaysMap = partnerDailyInvestmentRepository.selectAll(LocalDate.now().withDayOfMonth(1), LocalDate.now()).stream().collect(groupingBy(
35848 amit 1800
                x -> x.getFofoId(), Collectors.summingInt(x -> x.getShortPercentage() > ProfitMandiConstants.OK_INVESTMENT_SHORT_PERCENTAGE ? 1 : 0)));
24271 amit.gupta 1801
 
31697 amit.gupta 1802
        for (FofoStore fofoStore : fofoStores) {
1803
            LOGGER.info("Fofo Store {},  {}", fofoStore.getId(), fofoStore.getCode());
1804
            int fofoId = fofoStore.getId();
1805
            PartnerDailyInvestment partnerDailyInvestment = partnerInvestmentService.getInvestment(fofoId, 1);
1806
            partnerDailyInvestment.setDate(yesterDay);
24177 govind 1807
 
31697 amit.gupta 1808
            try {
1809
                partnerDailyInvestmentRepository.persist(partnerDailyInvestment);
35848 amit 1810
                shortDaysMap.put(fofoId, shortDaysMap.get(fofoId) + (partnerDailyInvestment.getShortPercentage() > ProfitMandiConstants.OK_INVESTMENT_SHORT_PERCENTAGE ? 1 : 0));
31697 amit.gupta 1811
            } catch (Exception e) {
1812
                // ignore the exceptions during persist
1813
            }
25598 amit.gupta 1814
 
31697 amit.gupta 1815
            CustomRetailer retailer = customRetailerMap.get(fofoStore.getId());
1816
            if (retailer == null || partnerIdSalesHeaderMap.get(fofoStore.getId()) == null) {
1817
                LOGGER.info("Could not find retailer with retailer Id {}", fofoStore.getId());
1818
                continue;
1819
            }
1820
            FofoReportingModel reportingModel = partnerIdSalesHeaderMap.get(fofoStore.getId());
1821
            List<Serializable> row = new ArrayList<>();
31886 tejbeer 1822
            row.addAll(Arrays.asList(reportingModel.getCode(), reportingModel.getBusinessName(), reportingModel.getRegionalManager(), reportingModel.getTerritoryManager()));
31697 amit.gupta 1823
            row.addAll(
31886 tejbeer 1824
                    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)));
31697 amit.gupta 1825
            partnerRowsMap.put(fofoStore.getId(), row);
1826
            rows.add(row);
25837 amit.gupta 1827
 
31697 amit.gupta 1828
        }
25837 amit.gupta 1829
 
34611 ranu 1830
        String fileName = "InvestmentSummary-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv";
25837 amit.gupta 1831
 
34337 amit.gupta 1832
        if (sendTo == null) {
33452 amit.gupta 1833
            for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMapping().entrySet()) {
31886 tejbeer 1834
                List<List<?>> filteredRows = storeGuyEntry.getValue().stream().map(x -> partnerRowsMap.get(x)).filter(x -> x != null).collect(Collectors.toList());
31697 amit.gupta 1835
                ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, filteredRows);
1836
                String[] sendToArray = new String[]{storeGuyEntry.getKey()};
36460 ranu 1837
                Utils.sendMailWithAttachment(googleMailSender, sendToArray, null, "Franchise Investment Summary", "PFA", fileName, new ByteArrayResource(baos.toByteArray()));
31697 amit.gupta 1838
            }
36936 vikas 1839
            sendTo = Arrays.asList("tarun.verma@smartdukaan.com", "kamini.sharma@smartdukaan.com", "neeraj.gupta@smartdukaan.com", "amit.gupta@shop2020.in", "niranjan.kala@smartdukaan.com");
31697 amit.gupta 1840
        }
25837 amit.gupta 1841
 
31697 amit.gupta 1842
        ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, rows);
1843
        String[] sendToArray = sendTo.toArray(new String[sendTo.size()]);
36460 ranu 1844
        Utils.sendMailWithAttachment(googleMailSender, sendToArray, null, "Franchise Investment Summary", "PFA", fileName, new ByteArrayResource(baos.toByteArray()));
25837 amit.gupta 1845
 
31697 amit.gupta 1846
    }
25598 amit.gupta 1847
 
33256 amit.gupta 1848
    private Map<Integer, FofoReportingModel> getPartnerIdSalesHeaders() throws ProfitMandiBusinessException {
31697 amit.gupta 1849
        Map<String, SaleRoles> partnerEmailSalesMap = new HashMap<>();
1850
        Map<String, SaleRoles> partnerEmailRBMMap = new HashMap<>();
34903 ranu 1851
        Map<String, SaleRoles> partnerEmailABMMap = new HashMap<>();
24271 amit.gupta 1852
 
35521 amit 1853
        List<Position> positions = positionRepository.selectPositionByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_ABM));
31886 tejbeer 1854
        Map<Integer, AuthUser> authUsersMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
31697 amit.gupta 1855
        Map<Integer, List<CustomRetailer>> positionIdRetailerMap = csService.getPositionCustomRetailerMap(positions);
1856
        for (Position position : positions) {
1857
            List<CustomRetailer> crList = positionIdRetailerMap.get(position.getId());
1858
            if (crList == null)
1859
                continue;
1860
            if (position.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_SALES) {
1861
                for (CustomRetailer cr : crList) {
1862
                    if (!partnerEmailSalesMap.containsKey(cr.getEmail())) {
1863
                        partnerEmailSalesMap.put(cr.getEmail(), new SaleRoles());
1864
                    }
1865
                    SaleRoles saleRoles = partnerEmailSalesMap.get(cr.getEmail());
1866
                    AuthUser authUser = authUsersMap.get(position.getAuthUserId());
1867
                    if (authUser == null) {
1868
                        continue;
1869
                    }
1870
                    String name = authUser.getFirstName() + " " + authUser.getLastName();
1871
                    if (position.getEscalationType().equals(EscalationType.L1)) {
1872
                        saleRoles.getL1().add(name);
1873
                    } else if (position.getEscalationType().equals(EscalationType.L2)) {
1874
                        saleRoles.getL2().add(name);
1875
                    }
1876
                }
1877
            }
1878
            if (position.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_RBM) {
1879
                for (CustomRetailer cr : crList) {
1880
                    if (!partnerEmailRBMMap.containsKey(cr.getEmail())) {
1881
                        partnerEmailRBMMap.put(cr.getEmail(), new SaleRoles());
1882
                    }
1883
                    SaleRoles saleRoles = partnerEmailRBMMap.get(cr.getEmail());
1884
                    AuthUser authUser = authUsersMap.get(position.getAuthUserId());
1885
                    if (authUser == null) {
1886
                        continue;
1887
                    }
1888
                    String name = authUser.getFirstName() + " " + authUser.getLastName();
1889
                    if (position.getEscalationType().equals(EscalationType.L1) || position.getEscalationType().equals(EscalationType.L1)) {
1890
                        saleRoles.getL1().add(name);
1891
                    }
1892
                    /*else if (position.getEscalationType().equals(EscalationType.L2)) {
1893
                        saleRoles.getL2().add(name);
1894
                    }*/
1895
                }
1896
            }
24692 amit.gupta 1897
 
34903 ranu 1898
            if (position.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_ABM) {
1899
                for (CustomRetailer cr : crList) {
1900
                    if (!partnerEmailABMMap.containsKey(cr.getEmail())) {
1901
                        partnerEmailABMMap.put(cr.getEmail(), new SaleRoles());
1902
                    }
1903
                    SaleRoles saleRoles = partnerEmailABMMap.get(cr.getEmail());
1904
                    AuthUser authUser = authUsersMap.get(position.getAuthUserId());
1905
                    if (authUser == null) {
1906
                        continue;
1907
                    }
1908
                    String name = authUser.getFirstName() + " " + authUser.getLastName();
1909
                    if (position.getEscalationType().equals(EscalationType.L1) || position.getEscalationType().equals(EscalationType.L1)) {
1910
                        saleRoles.getL1().add(name);
35521 amit 1911
                    } else if (position.getEscalationType().equals(EscalationType.L2)) {
34903 ranu 1912
                        saleRoles.getL2().add(name);
1913
                    }
1914
                }
1915
            }
1916
 
31697 amit.gupta 1917
        }
25418 amit.gupta 1918
 
31697 amit.gupta 1919
        Set<CustomRetailer> allCrList = new HashSet<>();
1920
        for (List<CustomRetailer> cr : positionIdRetailerMap.values()) {
1921
            allCrList.addAll(cr);
1922
        }
25609 amit.gupta 1923
 
31886 tejbeer 1924
        Map<Integer, FofoStore> fofoStoresMap = fofoStoreRepository.selectActiveStores().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
25503 amit.gupta 1925
 
31697 amit.gupta 1926
        Map<Integer, FofoReportingModel> partnerIdSalesHeadersMap = new HashMap<>();
25503 amit.gupta 1927
 
31697 amit.gupta 1928
        for (CustomRetailer cr : allCrList) {
1929
            FofoStore fofoStore = fofoStoresMap.get(cr.getPartnerId());
1930
            if (fofoStore == null) {
1931
                LOGGER.info("Could not find Store {} in active Store", cr.getBusinessName());
1932
                continue;
1933
            }
1934
            String code = fofoStore.getCode();
1935
            // String storeName = "SmartDukaan-" +
1936
            // fofoStore.getCode().replaceAll("[a-zA-Z]", "");
1937
            String businessName = cr.getBusinessName();
1938
            try {
1939
                String stateManager = StringUtils.join(partnerEmailSalesMap.get(cr.getEmail()).getL2(), ", ");
1940
                String territoryManager = StringUtils.join(partnerEmailSalesMap.get(cr.getEmail()).getL1(), ", ");
1941
                String bdm = StringUtils.join(partnerEmailRBMMap.get(cr.getEmail()).getL1(), ", ");
1942
                FofoReportingModel reportingModel = new FofoReportingModel();
1943
                reportingModel.setBusinessName(businessName);
1944
                reportingModel.setCode(code);
1945
                reportingModel.setFofoId(fofoStore.getId());
1946
                reportingModel.setRegionalManager(stateManager);
1947
                reportingModel.setTerritoryManager(territoryManager);
1948
                reportingModel.setBusinessManager(bdm);
1949
                partnerIdSalesHeadersMap.put(fofoStore.getId(), reportingModel);
1950
            } catch (Exception e) {
1951
                LOGGER.warn("Could not find partner with email - {}", cr.getEmail());
1952
            }
1953
        }
1954
        return partnerIdSalesHeadersMap;
24533 govind 1955
 
31697 amit.gupta 1956
    }
28709 amit.gupta 1957
 
34275 tejus.loha 1958
    public void persistRbmTodayTargets() throws Exception {
33928 ranu 1959
        rbmTargetService.setMovementWiseRbmTargets();
1960
    }
1961
 
34275 tejus.loha 1962
    public void persistRbmTodayAchievements() throws Exception {
33986 ranu 1963
        rbmTargetService.setMovementWiseRbmAchievement();
1964
    }
1965
 
31697 amit.gupta 1966
    public void sendPartnerInvestmentDetails() throws Exception {
1967
        this.sendPartnerInvestmentDetails(null);
1968
    }
28709 amit.gupta 1969
 
31697 amit.gupta 1970
    public void sendAgeingReport(String... sendTo) throws Exception {
28790 amit.gupta 1971
 
31886 tejbeer 1972
        InputStreamSource isr = reporticoService.getReportInputStreamSource(ReporticoProject.WAREHOUSENEW, "itemstockageing.xml");
1973
        InputStreamSource isr1 = reporticoService.getReportInputStreamSource(ReporticoProject.FOCO, "ItemwiseOverallPendingIndent.xml");
31697 amit.gupta 1974
        Attachment attachment = new Attachment(
1975
                "ageing-report-" + FormattingUtils.formatDate(LocalDateTime.now().minusDays(1)) + ".csv", isr);
1976
        Attachment attachment1 = new Attachment(
1977
                "pending-indent-" + FormattingUtils.formatDate(LocalDateTime.now().minusDays(1)) + ".csv", isr1);
28790 amit.gupta 1978
 
35959 amit 1979
        mailOutboxService.queueMailWithAttachmentsViaGoogle(STOCK_AGEING_MAIL_LIST, null, "Stock Ageing Report", "PFA", "ScheduledTasks.sendAgeingReport", attachment);
1980
        mailOutboxService.queueMailWithAttachmentsViaGoogle(ITEMWISE_PENDING_INDENT_MAIL_LIST, null, "Itemwise Pending indent", "PFA", "ScheduledTasks.sendAgeingReport", attachment1);
28790 amit.gupta 1981
 
31697 amit.gupta 1982
        // Reports to be sent to mapped partners
1983
        Map<String, Set<String>> storeGuysMap = csService.getAuthUserPartnerEmailMapping();
28790 amit.gupta 1984
 
33452 amit.gupta 1985
        for (Entry<String, Set<String>> storeGuyEntry : storeGuysMap.entrySet()) {
31697 amit.gupta 1986
            Map<String, String> params = new HashMap<>();
1987
            if (storeGuyEntry.getValue().size() == 0)
1988
                continue;
1989
            params.put("MANUAL_email", String.join(",", storeGuyEntry.getValue()));
31886 tejbeer 1990
            InputStreamSource isr3 = reporticoService.getReportInputStreamSource(ReporticoProject.FOCO, "focostockreport.xml", params);
31697 amit.gupta 1991
            Attachment attache = new Attachment(
1992
                    "Franchise-stock-report" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv", isr3);
1993
            System.out.println(storeGuyEntry.getValue());
35959 amit 1994
            mailOutboxService.queueMailWithAttachmentsViaGoogle(new String[]{storeGuyEntry.getKey()}, null, "Franchise Stock Report", "PFA", "ScheduledTasks.sendAgeingReport", attache);
31697 amit.gupta 1995
        }
28839 tejbeer 1996
 
31697 amit.gupta 1997
    }
28839 tejbeer 1998
 
31697 amit.gupta 1999
    public void sendIndentTertiary() throws Exception {
28790 amit.gupta 2000
 
31886 tejbeer 2001
        InputStreamSource isr = reporticoService.getReportInputStreamSource(ReporticoProject.FOCO, "indentandtertiary.xml");
31697 amit.gupta 2002
        Attachment attachment = new Attachment(
2003
                "indentandtertiary-report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv", isr);
35959 amit 2004
        mailOutboxService.queueMailWithAttachmentsViaGoogle(INDENT_TERTIARY_MAIL_LIST, null, "Indent Tertiary Report", "PFA", "ScheduledTasks.sendIndentTertiary", attachment);
28790 amit.gupta 2005
 
31697 amit.gupta 2006
    }
28790 amit.gupta 2007
 
31697 amit.gupta 2008
    public void sendAttendanceMorningAlert() throws Exception {
2009
        LocalDateTime moriningTime = LocalDate.now().atTime(10, 31);
2010
        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
31886 tejbeer 2011
        Map<String, AuthUser> authUserEmailMap = authUsers.stream().filter(x -> x.isActive()).collect(Collectors.toMap(x -> x.getEmailId(), x -> x));
28775 amit.gupta 2012
 
31697 amit.gupta 2013
        List<User> users = dtrUserRepository.selectAllByEmailIds(new ArrayList<>(authUserEmailMap.keySet()));
2014
        Map<String, User> userMap = users.stream().collect(Collectors.toMap(x -> x.getEmailId(), x -> x));
28790 amit.gupta 2015
 
31886 tejbeer 2016
        List<EmployeeAttendance> employeeAttendances = employeeAttendanceRepository.selectAllByDatesBetween(LocalDate.now().atStartOfDay(), LocalDateTime.now());
28784 amit.gupta 2017
 
31886 tejbeer 2018
        Map<Integer, Optional<EmployeeAttendance>> employeeMorningAttendance = employeeAttendances.stream().collect(groupingBy(EmployeeAttendance::getUserId, Collectors.minBy(Comparator.comparing(EmployeeAttendance::getCreateTimestamp))));
31697 amit.gupta 2019
        for (AuthUser authUser : authUsers) {
2020
            User user = userMap.get(authUser.getEmailId());
2021
            Optional<EmployeeAttendance> employeeAttendanceOptional = employeeMorningAttendance.get(user.getId());
2022
            LOGGER.info("AuthUser - {}, employeeAttendanceOptional {}", authUser.getName(), employeeAttendanceOptional);
2023
            if (employeeAttendanceOptional != null) {
2024
                LOGGER.info("employeeAttendanceOptional.orElse {}", employeeAttendanceOptional.orElse(null));
2025
                if (employeeAttendanceOptional.orElse(null) != null) {
31886 tejbeer 2026
                    LOGGER.info("employeeAttendanceOptional.get().getCreateTimestamp() {}", employeeAttendanceOptional.get().getCreateTimestamp());
31697 amit.gupta 2027
                }
2028
            }
31886 tejbeer 2029
            if (employeeAttendanceOptional == null || employeeAttendanceOptional.orElse(null) == null || employeeAttendanceOptional.get().getCreateTimestamp().isAfter(moriningTime)) {
31697 amit.gupta 2030
                LOGGER.info("Will Send Email to {}", authUser.getFullName());
2031
                String body = String.format(
31886 tejbeer 2032
                        "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()) + ")");
28790 amit.gupta 2033
 
35959 amit 2034
                mailOutboxService.queueMailViaGoogle(new String[]{authUser.getEmailId()}, new String[]{"kangan.monga@smartdukaan.com"}, "Attendance Alert", body, "ScheduledTasks.sendAttendanceMorningAlert");
28790 amit.gupta 2035
 
31697 amit.gupta 2036
            }
2037
        }
28790 amit.gupta 2038
 
31697 amit.gupta 2039
    }
28790 amit.gupta 2040
 
31697 amit.gupta 2041
    public void sendAttendanceEveningAlert() throws Exception {
2042
        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
31886 tejbeer 2043
        Map<String, AuthUser> authUserEmailMap = authUsers.stream().filter(x -> x.isActive()).collect(Collectors.toMap(x -> x.getEmailId(), x -> x));
28709 amit.gupta 2044
 
31697 amit.gupta 2045
        List<User> users = dtrUserRepository.selectAllByEmailIds(new ArrayList<>(authUserEmailMap.keySet()));
2046
        Map<String, User> userMap = users.stream().collect(Collectors.toMap(x -> x.getEmailId(), x -> x));
28709 amit.gupta 2047
 
31886 tejbeer 2048
        Map<Integer, List<EmployeeAttendance>> employeeAttendancesMap = employeeAttendanceRepository.selectAllByDatesBetween(LocalDate.now().atStartOfDay(), LocalDateTime.now()).stream().collect(groupingBy(x -> x.getUserId()));
28709 amit.gupta 2049
 
31697 amit.gupta 2050
        for (AuthUser authUser : authUsers) {
2051
            User user = userMap.get(authUser.getEmailId());
2052
            String body = null;
2053
            List<EmployeeAttendance> employeeAttendances = employeeAttendancesMap.get(user.getId());
2054
            if (employeeAttendances == null) {
2055
                body = String.format(
31886 tejbeer 2056
                        "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());
31697 amit.gupta 2057
            } else {
31886 tejbeer 2058
                List<LocalDateTime> punchTimes = employeeAttendances.stream().sorted(Comparator.comparing(EmployeeAttendance::getCreateTimestamp)).map(x -> x.getCreateTimestamp()).collect(Collectors.toList());
31697 amit.gupta 2059
                if (punchTimes.size() == 1) {
2060
                    // body = String.format("Dear %s,\n Pls note that you haven't punched out yet.
2061
                    // You have been marked absent for half the day. You may contact your manager
2062
                    // and get it regularise.\n\nRegards\nHR Team", authUser.getFullName());
2063
                } else {
2064
                    LocalDateTime firstPunch = punchTimes.get(0);
2065
                    LocalDateTime lastPunch = punchTimes.get(punchTimes.size() - 1);
2066
                    Duration duration = Duration.between(firstPunch, lastPunch);
2067
                    boolean hoursCompleted = lastPunch.isAfter(firstPunch.plusHours(8).plusMinutes(30));
2068
                    if (!hoursCompleted) {
2069
                        body = String.format(
31886 tejbeer 2070
                                "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);
31697 amit.gupta 2071
                    }
2072
                }
28709 amit.gupta 2073
 
31697 amit.gupta 2074
            }
2075
            if (body != null) {
35959 amit 2076
                mailOutboxService.queueMailViaGoogle(new String[]{authUser.getEmailId()}, new String[]{"kangan.monga@smartdukaan.com"}, "Attendance Alert", body, "ScheduledTasks.sendAttendanceEveningAlert");
31697 amit.gupta 2077
            }
2078
        }
28709 amit.gupta 2079
 
31697 amit.gupta 2080
        this.sendMailToHR();
28709 amit.gupta 2081
 
31697 amit.gupta 2082
    }
28709 amit.gupta 2083
 
31697 amit.gupta 2084
    private void sendMailToHR() throws Exception {
2085
        Map<String, String> map = new HashMap<>();
2086
        String reporticoDate = FormattingUtils.formatReporitcoDate(LocalDateTime.now());
2087
        map.put("MANUAL_datesBetween_FROMDATE", reporticoDate);
2088
        map.put("MANUAL_datesBetween_FROMDATE", reporticoDate);
31886 tejbeer 2089
        InputStreamSource isr = reporticoService.getReportInputStreamSource(ReporticoProject.FOCO, "employeeattendance.xml");
2090
        Attachment attachment = new Attachment("attendance-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv", isr);
35959 amit 2091
        mailOutboxService.queueMailWithAttachmentsViaGoogle(EMPLOYEE_ATTENDANCE_MAIL_LIST, null, "Attendance - " + FormattingUtils.formatDate(LocalDateTime.now()), "PFA Attendance", "ScheduledTasks.sendMailToHR", attachment);
31697 amit.gupta 2092
    }
28709 amit.gupta 2093
 
31697 amit.gupta 2094
    public void checkPartnerActiveStore() throws Exception {
24697 amit.gupta 2095
 
31697 amit.gupta 2096
        List<FofoStore> fofoStores = fofoStoreRepository.selectByStatus(true);
23929 amit.gupta 2097
 
31697 amit.gupta 2098
        LocalDateTime currentDate = LocalDate.now().atStartOfDay();
2099
        if (!fofoStores.isEmpty()) {
2100
            for (FofoStore fofoStore : fofoStores) {
24551 amit.gupta 2101
 
31697 amit.gupta 2102
                if (currentDate.isBefore(fofoStore.getActiveTimeStamp())) {
24542 amit.gupta 2103
 
31697 amit.gupta 2104
                    fofoStore.setActive(true);
2105
                    fofoStoreRepository.persist(fofoStore);
2106
                    LOGGER.info("inserted into InActiveFofoStore successfully");
29160 amit.gupta 2107
 
31697 amit.gupta 2108
                } else {
2109
                    fofoStore.setActive(false);
2110
                    fofoStore.setActiveTimeStamp(null);
2111
                    fofoStoreRepository.persist(fofoStore);
2112
                    LOGGER.info("inserted into InActiveFofoStore successfully");
2113
                }
24542 amit.gupta 2114
 
31697 amit.gupta 2115
            }
2116
        }
24542 amit.gupta 2117
 
31697 amit.gupta 2118
    }
24548 amit.gupta 2119
 
37040 ranu 2120
    public void updatePartnerActivationTypeByMonthlySale() throws Exception {
2121
        LocalDateTime now = LocalDateTime.now();
2122
        LocalDateTime thirtyDaysAgo = now.minusDays(30);
2123
        LocalDateTime sixtyDaysAgo = now.minusDays(60);
2124
        long threshold = 99_999L;
2125
 
37154 ranu 2126
        // Include REVIVAL now so previously-downgraded stores can be promoted back to ACTIVE
2127
        // when they resume billing above the threshold in the last 30 days.
37043 ranu 2128
        List<FofoStore> candidates = fofoStoreRepository.selectAllFranchiseStores().stream()
2129
                .filter(s -> s.isActive() && !s.isInternal() && !s.isClosed())
2130
                .filter(s -> s.getActivationType() == ActivationType.ACTIVE
37154 ranu 2131
                        || s.getActivationType() == ActivationType.FOCUS
2132
                        || s.getActivationType() == ActivationType.REVIVAL)
37043 ranu 2133
                .collect(Collectors.toList());
37040 ranu 2134
 
2135
        if (candidates.isEmpty()) {
2136
            LOGGER.info("updatePartnerActivationTypeByMonthlySale: no candidate stores");
2137
            return;
2138
        }
2139
 
2140
        List<Integer> ids = candidates.stream().map(FofoStore::getId).collect(Collectors.toList());
2141
        Set<Integer> met30 = orderRepository.selectFofoIdsWithMtdBillingAboveThreshold(ids, thirtyDaysAgo, now, threshold);
2142
        Set<Integer> met60 = orderRepository.selectFofoIdsWithMtdBillingAboveThreshold(ids, sixtyDaysAgo, now, threshold);
2143
 
2144
        int toFocus = 0;
2145
        int toRevival = 0;
37154 ranu 2146
        int toActive = 0;
37040 ranu 2147
        for (FofoStore store : candidates) {
2148
            int id = store.getId();
37154 ranu 2149
            boolean above30 = met30.contains(id);
2150
            boolean below30 = !above30;
37040 ranu 2151
            boolean below60 = !met60.contains(id);
2152
            ActivationType current = store.getActivationType();
2153
            ActivationType target = current;
2154
 
37154 ranu 2155
            // Promotion — asymmetric windows by current status:
2156
            //   FOCUS   → ACTIVE if billed > ₹99,999 in the last 30 days (recent activity required)
2157
            //   REVIVAL → ACTIVE if billed > ₹99,999 in the last 60 days (deeper trouble, so any
2158
            //             sign of life in the last 2 months earns a promotion)
2159
            // Evaluated ahead of the downgrade rules so a recently-billing REVIVAL isn't held at
2160
            // REVIVAL by the below60 rule below.
2161
            if (current == ActivationType.FOCUS && above30) {
2162
                target = ActivationType.ACTIVE;
2163
            } else if (current == ActivationType.REVIVAL && met60.contains(id)) {
2164
                target = ActivationType.ACTIVE;
2165
            } else if (below60) {
37040 ranu 2166
                target = ActivationType.REVIVAL;
2167
            } else if (below30 && current == ActivationType.ACTIVE) {
2168
                target = ActivationType.FOCUS;
2169
            }
2170
 
2171
            if (target != current) {
37154 ranu 2172
                // Safety guard only applies to downgrades — never auto-downgrade a store that
2173
                // has never billed yet. Promotions to ACTIVE always allowed (billing observed).
2174
                if (target != ActivationType.ACTIVE) {
2175
                    LocalDateTime firstBillingDate = transactionRepository.getFirstBillingDate(id);
2176
                    if (firstBillingDate == null) {
2177
                        LOGGER.info("Skip auto-downgrade fofoId={} code={}: first billing pending",
2178
                                id, store.getCode());
2179
                        continue;
2180
                    }
37128 ranu 2181
                }
37154 ranu 2182
                LOGGER.info("Auto-{} fofoId={} code={} from {} to {} (above30={}, below60={})",
2183
                        target == ActivationType.ACTIVE ? "promote" : "downgrade",
2184
                        id, store.getCode(), current, target, above30, below60);
37040 ranu 2185
                store.setActivationType(target);
2186
                fofoStoreRepository.persist(store);
2187
                if (target == ActivationType.FOCUS) {
2188
                    toFocus++;
37154 ranu 2189
                } else if (target == ActivationType.REVIVAL) {
37040 ranu 2190
                    toRevival++;
37154 ranu 2191
                } else if (target == ActivationType.ACTIVE) {
2192
                    toActive++;
37040 ranu 2193
                }
2194
            }
2195
        }
37154 ranu 2196
        LOGGER.info("updatePartnerActivationTypeByMonthlySale done: scanned={}, toFocus={}, toRevival={}, toActive={}",
2197
                candidates.size(), toFocus, toRevival, toActive);
37040 ranu 2198
    }
2199
 
31697 amit.gupta 2200
    public void sendAgeingReport() throws Exception {
33820 ranu 2201
        sendAgeingReport("kamini.sharma@smartdukaan.com", "tarun.verma@smartdukaan.com", "niranjan.kala@smartdukaan.com", "kuldeep.kumar@smartdukaan.com");
31697 amit.gupta 2202
    }
24542 amit.gupta 2203
 
31697 amit.gupta 2204
    public void moveImeisToPriceDropImeis() throws Exception {
2205
        List<PriceDrop> priceDrops = priceDropRepository.selectAll();
2206
        for (PriceDrop priceDrop : priceDrops) {
2207
            priceDropService.priceDropStatus(priceDrop.getId());
2208
        }
2209
    }
29160 amit.gupta 2210
 
31697 amit.gupta 2211
    public void walletmismatch() throws Exception {
2212
        LocalDate curDate = LocalDate.now();
2213
        List<PartnerDailyInvestment> pdis = partnerDailyInvestmentRepository.selectAll(curDate.minusDays(2));
2214
        System.out.println(pdis.size());
2215
        for (PartnerDailyInvestment pdi : pdis) {
2216
            int fofoId = pdi.getFofoId();
31886 tejbeer 2217
            for (PartnerDailyInvestment investment : Lists.reverse(partnerDailyInvestmentRepository.selectAll(fofoId, null, null))) {
2218
                float statementAmount = walletService.getOpeningTill(fofoId, investment.getDate().plusDays(1).atTime(LocalTime.of(4, 0)));
31697 amit.gupta 2219
                CustomRetailer retailer = retailerService.getFofoRetailer(fofoId);
31886 tejbeer 2220
                LOGGER.info("{}\t{}\t{}\t{}\t{}", fofoId, retailer.getBusinessName(), retailer.getMobileNumber(), investment.getDate().toString(), investment.getWalletAmount(), statementAmount);
29160 amit.gupta 2221
 
31697 amit.gupta 2222
            }
2223
        }
29160 amit.gupta 2224
 
31697 amit.gupta 2225
    }
29160 amit.gupta 2226
 
31697 amit.gupta 2227
    @Autowired
2228
    StateRepository stateRepository;
29160 amit.gupta 2229
 
31697 amit.gupta 2230
    public void gst() throws Exception {
31886 tejbeer 2231
        List<FofoOrder> fofoOrders = fofoOrderRepository.selectBetweenSaleDate(LocalDate.of(2021, 8, 16).atStartOfDay(), LocalDateTime.now());
31697 amit.gupta 2232
        for (FofoOrder fofoOrder : fofoOrders) {
31886 tejbeer 2233
            int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoOrder.getFofoId());
24548 amit.gupta 2234
 
31697 amit.gupta 2235
            Address retailerAddress = addressRepository.selectById(retailerAddressId);
2236
            CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());
2237
            Integer stateId = null;
2238
            if (customerAddress.getState().equals(retailerAddress.getState())) {
2239
                try {
2240
                    stateId = stateRepository.selectByName(customerAddress.getState()).getId();
2241
                } catch (Exception e) {
2242
                    LOGGER.error("Cannot found state named {}", customerAddress.getState());
2243
                    continue;
2244
                }
2245
            }
2246
            Map<Integer, GstRate> itemIdStateTaxRateMap = null;
24542 amit.gupta 2247
 
31697 amit.gupta 2248
            List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
2249
            List<Integer> itemIds = fofoOrderItems.stream().map(x -> x.getItemId()).collect(Collectors.toList());
2250
            if (stateId != null) {
2251
                itemIdStateTaxRateMap = stateGstRateRepository.getStateTaxRate(itemIds, stateId);
2252
            } else {
32145 tejbeer 2253
                itemIdStateTaxRateMap = stateGstRateRepository.getIgstTaxRate(itemIds);
31697 amit.gupta 2254
            }
24580 amit.gupta 2255
 
31697 amit.gupta 2256
            for (FofoOrderItem foi : fofoOrderItems) {
2257
                float sgstRate = foi.getSgstRate();
2258
                float cgstRate = foi.getCgstRate();
2259
                float igstRate = foi.getIgstRate();
32145 tejbeer 2260
                foi.setCgstRate(itemIdStateTaxRateMap.get(foi.getItemId()).getCgstRate());
2261
                foi.setSgstRate(itemIdStateTaxRateMap.get(foi.getItemId()).getSgstRate());
2262
                foi.setIgstRate(itemIdStateTaxRateMap.get(foi.getItemId()).getIgstRate());
24587 amit.gupta 2263
 
32145 tejbeer 2264
                LOGGER.info("Invoice {}, Date {}", fofoOrder.getInvoiceNumber(), fofoOrder.getCreateTimestamp());
2265
                LOGGER.info("customerAddress.getState() {}, retailerAddress.getState() {}", customerAddress.getState(), retailerAddress.getState());
2266
                LOGGER.info("Rates getIgstRate() {}", itemIdStateTaxRateMap.get(foi.getItemId()).getIgstRate());
2267
                LOGGER.info("Rates getCgstRate() {}, getSgstRate() {}", itemIdStateTaxRateMap.get(foi.getItemId()).getCgstRate(), itemIdStateTaxRateMap.get(foi.getItemId()).getSgstRate());
24587 amit.gupta 2268
 
2269
 
31697 amit.gupta 2270
            }
2271
        }
26092 amit.gupta 2272
 
31697 amit.gupta 2273
    }
24590 amit.gupta 2274
 
33256 amit.gupta 2275
    public void schemewalletmismatch() throws ProfitMandiBusinessException {
31697 amit.gupta 2276
        LocalDate dateToReconcile = LocalDate.of(2018, 4, 1);
2277
        while (dateToReconcile.isBefore(LocalDate.now())) {
2278
            reconcileSchemes(dateToReconcile);
2279
            // reconcileOrders(dateTime);
2280
            // reconcileRecharges(dateTime);
2281
            dateToReconcile = dateToReconcile.plusDays(1);
2282
        }
2283
    }
24587 amit.gupta 2284
 
33256 amit.gupta 2285
    private void reconcileSchemes(LocalDate date) throws ProfitMandiBusinessException {
31697 amit.gupta 2286
        LocalDateTime startDate = date.atStartOfDay();
2287
        LocalDateTime endDate = startDate.plusDays(1);
2288
        List<SchemeInOut> siosCreated = schemeInOutRepository.selectAllByCreateDate(startDate, endDate);
2289
        List<SchemeInOut> siosRefunded = schemeInOutRepository.selectAllByRefundDate(startDate, endDate);
2290
        double totalSchemeDisbursed = siosCreated.stream().mapToDouble(x -> x.getAmount()).sum();
2291
        double totalSchemeRolledback = siosRefunded.stream().mapToDouble(x -> x.getAmount()).sum();
2292
        double netSchemeDisbursed = totalSchemeDisbursed - totalSchemeRolledback;
31886 tejbeer 2293
        List<WalletReferenceType> walletReferenceTypes = Arrays.asList(WalletReferenceType.SCHEME_IN, WalletReferenceType.SCHEME_OUT);
2294
        List<UserWalletHistory> history = userWalletHistoryRepository.selectAllByDateType(startDate, endDate, walletReferenceTypes);
31697 amit.gupta 2295
        double schemeAmountWalletTotal = history.stream().mapToDouble(x -> x.getAmount()).sum();
2296
        if (Math.abs(netSchemeDisbursed - schemeAmountWalletTotal) > 10d) {
2297
            LOGGER.info("Scheme Amount mismatched for Date {}", date);
24590 amit.gupta 2298
 
31724 amit.gupta 2299
            Map<Integer, Double> inventoryItemSchemeIO = siosCreated.stream().collect(groupingBy(x -> x.getInventoryItemId(), Collectors.summingDouble(SchemeInOut::getAmount)));
24635 amit.gupta 2300
 
31886 tejbeer 2301
            Map<Integer, Double> userSchemeMap = inventoryItemRepository.selectByIds(inventoryItemSchemeIO.keySet()).stream().collect(groupingBy(x -> x.getFofoId(), Collectors.summingDouble(x -> inventoryItemSchemeIO.get(x.getId()))));
24635 amit.gupta 2302
 
31724 amit.gupta 2303
            Map<Integer, Double> inventoryItemSchemeIORefunded = siosRefunded.stream().collect(groupingBy(x -> x.getInventoryItemId(), Collectors.summingDouble(SchemeInOut::getAmount)));
24635 amit.gupta 2304
 
31886 tejbeer 2305
            Map<Integer, Double> userSchemeRefundedMap = inventoryItemRepository.selectByIds(inventoryItemSchemeIORefunded.keySet()).stream().collect(groupingBy(x -> x.getFofoId(), Collectors.summingDouble(x -> inventoryItemSchemeIORefunded.get(x.getId()))));
24635 amit.gupta 2306
 
31697 amit.gupta 2307
            Map<Integer, Double> finalUserSchemeAmountMap = new HashMap<>();
24635 amit.gupta 2308
 
33452 amit.gupta 2309
            for (Entry<Integer, Double> schemeAmount : userSchemeRefundedMap.entrySet()) {
31697 amit.gupta 2310
                if (!finalUserSchemeAmountMap.containsKey(schemeAmount.getKey())) {
2311
                    finalUserSchemeAmountMap.put(schemeAmount.getKey(), schemeAmount.getValue());
2312
                } else {
31886 tejbeer 2313
                    finalUserSchemeAmountMap.put(schemeAmount.getKey(), finalUserSchemeAmountMap.get(schemeAmount.getKey()) + schemeAmount.getValue());
31697 amit.gupta 2314
                }
2315
            }
31886 tejbeer 2316
            Map<Integer, Integer> userWalletMap = userWalletRepository.selectByRetailerIds(finalUserSchemeAmountMap.keySet()).stream().collect(Collectors.toMap(UserWallet::getUserId, UserWallet::getId));
24635 amit.gupta 2317
 
31724 amit.gupta 2318
            Map<Integer, Double> walletAmountMap = history.stream().collect(groupingBy(
31697 amit.gupta 2319
                    UserWalletHistory::getWalletId, Collectors.summingDouble((UserWalletHistory::getAmount))));
33452 amit.gupta 2320
            for (Entry<Integer, Double> userAmount : walletAmountMap.entrySet()) {
31697 amit.gupta 2321
                double diff = Math.abs(finalUserSchemeAmountMap.get(userAmount.getKey()) - userAmount.getValue());
2322
                if (diff > 5) {
2323
                    LOGGER.info("Partner scheme mismatched for Userid {}", userWalletMap.get(userAmount.getKey()));
2324
                }
2325
            }
2326
        }
24635 amit.gupta 2327
 
31697 amit.gupta 2328
    }
24635 amit.gupta 2329
 
31697 amit.gupta 2330
    public void sendDailySalesNotificationToPartner(Integer fofoIdInt) throws Exception {
30982 tejbeer 2331
 
31697 amit.gupta 2332
        LocalDateTime now = LocalDateTime.now();
2333
        LocalDateTime from = now.with(LocalTime.MIN);
2334
        String timeString = "Today %s";
2335
        // Send yesterday's report
2336
        /*
2337
         * if (now.getHour() < 13) { timeString = "Yesterday %s"; from =
2338
         * now.minusDays(1).; now = from.with(LocalTime.MAX);
2339
         *
2340
         * }
2341
         */
30982 tejbeer 2342
 
31697 amit.gupta 2343
        List<Integer> fofoIds = null;
31886 tejbeer 2344
        Map<Integer, FofoStore> fofoStoreMap = fofoStoreRepository.selectAll().stream().filter(x -> x.isActive()).collect(Collectors.toMap(x -> x.getId(), x -> x));
30982 tejbeer 2345
 
24653 govind 2346
 
31697 amit.gupta 2347
        if (fofoIdInt == null) {
2348
            fofoIds = new ArrayList<>(fofoStoreMap.keySet());
2349
        } else {
2350
            fofoIds = Arrays.asList(fofoIdInt);
2351
        }
2352
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("h:m a");
28368 tejbeer 2353
 
31886 tejbeer 2354
        Map<Integer, Float> partnerPolicyAmountMap = insurancePolicyRepository.selectAmountSumGroupByRetailerId(now, null);
31697 amit.gupta 2355
        Map<Integer, Long> partnerPolicyQtyMap = insurancePolicyRepository.selectQtyGroupByRetailerId(now, null);
28368 tejbeer 2356
 
31886 tejbeer 2357
        Map<Integer, Double> spPartnerOrderValMap = fofoOrderItemRepository.selectSumAmountGroupByRetailer(from, now, 0, true);
28377 tejbeer 2358
 
31886 tejbeer 2359
        Map<Integer, Double> spPartner3DaysOrderValMap = fofoOrderItemRepository.selectSumAmountGroupByRetailer(from.minusDays(3), now, 0, true);
31697 amit.gupta 2360
        Map<Integer, Long> spPartnerOrderQtyMap = fofoOrderItemRepository.selectQtyGroupByRetailer(from, now, 0, true);
28368 tejbeer 2361
 
31886 tejbeer 2362
        Map<Integer, Double> partnerOrderValMap = fofoOrderItemRepository.selectSumAmountGroupByRetailer(from, now, 0, false);
31697 amit.gupta 2363
        Map<Integer, Long> partnerOrderQtyMap = fofoOrderItemRepository.selectQtyGroupByRetailer(from, now, 0, false);
28377 tejbeer 2364
 
31697 amit.gupta 2365
        //4 days + current day running
2366
        Map<Integer, Double> partnerBilledValueMap = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(from.minusDays(4), now);
28377 tejbeer 2367
 
31697 amit.gupta 2368
        Map<Integer, SaleTargetReportModel> saleTargetReportModelMap = new HashMap<>();
2369
        for (int fofoId : fofoIds) {
2370
            SaleTargetReportModel model = new SaleTargetReportModel();
2371
            model.setInsuranceSale(
2372
                    partnerPolicyAmountMap.containsKey(fofoId) ? partnerPolicyAmountMap.get(fofoId).doubleValue() : 0);
2373
            model.setInsruanceQty(partnerPolicyQtyMap.containsKey(fofoId) ? partnerPolicyQtyMap.get(fofoId) : 0);
2374
            model.setSecondary(partnerBilledValueMap.containsKey(fofoId) ? partnerBilledValueMap.get(fofoId) : 0);
2375
            model.setSmartphoneSale(spPartnerOrderValMap.containsKey(fofoId) ? spPartnerOrderValMap.get(fofoId) : 0);
2376
            model.setSmartphoneQty(spPartnerOrderQtyMap.containsKey(fofoId) ? spPartnerOrderQtyMap.get(fofoId) : 0);
2377
            model.setTotalSale(partnerOrderValMap.containsKey(fofoId) ? partnerOrderValMap.get(fofoId) : 0);
2378
            model.setTotalQty(partnerOrderQtyMap.containsKey(fofoId) ? partnerOrderQtyMap.get(fofoId) : 0);
2379
            model.setPast3daysSale(
2380
                    spPartner3DaysOrderValMap.containsKey(fofoId) ? spPartner3DaysOrderValMap.get(fofoId) : 0);
2381
            model.setFofoId(fofoId);
2382
            model.setCode(fofoStoreMap.get(fofoId).getCode());
31724 amit.gupta 2383
            model.setActivationType(fofoStoreMap.get(fofoId).getActivationType());
31697 amit.gupta 2384
            saleTargetReportModelMap.put(fofoId, model);
2385
        }
28377 tejbeer 2386
 
31697 amit.gupta 2387
        Map<Integer, FofoReportingModel> partnerSalesHeadersMap = this.getPartnerIdSalesHeaders();
2388
        for (Integer fofoId : fofoIds) {
2389
            SaleTargetReportModel model = saleTargetReportModelMap.get(fofoId);
28368 tejbeer 2390
 
31697 amit.gupta 2391
            // com.spice.profitmandi.dao.entity.user.User user =
2392
            // userUserRepository.selectById(fofoId);
28377 tejbeer 2393
 
31697 amit.gupta 2394
            // Address address = addressRepository.selectById(user.getAddressId());
28377 tejbeer 2395
 
31697 amit.gupta 2396
            String title = "Sale Update";
31886 tejbeer 2397
            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)));
31697 amit.gupta 2398
            SendNotificationModel sendNotificationModel = new SendNotificationModel();
2399
            sendNotificationModel.setCampaignName("Sales update alert");
2400
            sendNotificationModel.setTitle(title);
2401
            sendNotificationModel.setMessage(messageTemplate);
2402
            sendNotificationModel.setType("url");
2403
            sendNotificationModel.setUrl("https://app.smartdukaan.com/pages/home/notifications");
2404
            sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(1));
2405
            sendNotificationModel.setMessageType(MessageType.notification);
2406
            int userId = userAccountRepository.selectUserIdByRetailerId(fofoId);
2407
            sendNotificationModel.setUserIds(Arrays.asList(userId));
2408
            notificationService.sendNotification(sendNotificationModel);
2409
            String whatsappMessageTemplate = String.format(
31886 tejbeer 2410
                    "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)));
31697 amit.gupta 2411
            // notificationService.sendWhatsappMessage(whatsappMessageTemplate, title,
2412
            // address.getPhoneNumber());
28377 tejbeer 2413
 
31697 amit.gupta 2414
        }
2415
        // String saleReport = this.getDailySalesReportHtml(partnerSalesHeadersMap,
2416
        // saleTargetReportModelMap);
2417
        this.getStateWiseSales(saleTargetReportModelMap, partnerSalesHeadersMap);
2418
    }
28377 tejbeer 2419
 
31697 amit.gupta 2420
    public void checkRazorPayPaymentStatus() throws Exception {
31886 tejbeer 2421
        List<PendingOrder> pendingOrder = pendingOrderRepository.selectAllByStatus(com.spice.profitmandi.dao.enumuration.transaction.OrderStatus.PENDING);
28377 tejbeer 2422
 
31697 amit.gupta 2423
        for (PendingOrder po : pendingOrder) {
2424
            RazorPay razorPay = razorPayRepository.selectByOrdeId(po.getId());
2425
            List<PendingOrderItem> poItems = pendingOrderItemRepository.selectByOrderId(po.getId());
28369 tejbeer 2426
 
31697 amit.gupta 2427
            LOGGER.info("razorPay" + razorPay);
2428
            if (razorPay != null) {
2429
                List<Payment> payments = razorPaymentService.fetchOrderForPayment(razorPay.getRazorOrderId());
28368 tejbeer 2430
 
31697 amit.gupta 2431
                if (!payments.isEmpty()) {
2432
                    List<String> statusList = new ArrayList<>();
2433
                    for (Payment payment : payments) {
25880 amit.gupta 2434
 
31697 amit.gupta 2435
                        JSONObject jsonObj = new JSONObject(payment.toString());
25880 amit.gupta 2436
 
31697 amit.gupta 2437
                        String status = jsonObj.getString("status");
25880 amit.gupta 2438
 
31697 amit.gupta 2439
                        statusList.add(status);
25865 amit.gupta 2440
 
31697 amit.gupta 2441
                    }
2442
                    LOGGER.info("statusList" + statusList);
26941 amit.gupta 2443
 
31697 amit.gupta 2444
                    if (statusList.contains("authorized") || statusList.contains("captured")) {
2445
                        po.setStatus(com.spice.profitmandi.dao.enumuration.transaction.OrderStatus.PROCESSING);
2446
                        po.setPaidAmount(po.getTotalAmount());
2447
                        for (PendingOrderItem poi : poItems) {
2448
                            poi.setStatus(com.spice.profitmandi.dao.enumuration.transaction.OrderStatus.PROCESSING);
2449
                        }
2450
                        Map<String, Object> emailModel = pendingOrderService.sendCreateOrderMail(po);
26941 amit.gupta 2451
 
31697 amit.gupta 2452
                        CustomRetailer customRetailer = retailerService.getFofoRetailer(po.getFofoId());
2453
                        Customer customer = customerRepository.selectById(po.getCustomerId());
2454
                        String[] customerEmail = null;
2455
                        if (customer.getEmailId() != null) {
2456
                            customerEmail = new String[]{customer.getEmailId()};
2457
                        }
31886 tejbeer 2458
                        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());
31697 amit.gupta 2459
                        List<String> authUserEmails = csService.getAuthUserByPartnerId(customRetailer.getPartnerId());
2460
                        if (authUserEmails != null) {
2461
                            authUserEmails = new ArrayList<>();
2462
                        }
2463
                        authUserEmails.addAll(bccTo);
26945 amit.gupta 2464
 
31697 amit.gupta 2465
                        // emailService.sendMailWithAttachments("Order Created with SmartDukaan",
2466
                        // "order-confirm.vm",
2467
                        // emailModel, customerEmail, null, authUserEmails.toArray(new String[0]));
26945 amit.gupta 2468
 
31697 amit.gupta 2469
                    } else if (statusList.contains("refunded") || statusList.contains("failed")) {
2470
                        for (PendingOrderItem poi : poItems) {
2471
                            poi.setStatus(com.spice.profitmandi.dao.enumuration.transaction.OrderStatus.FAILED);
2472
                        }
25865 amit.gupta 2473
 
31697 amit.gupta 2474
                        po.setStatus(com.spice.profitmandi.dao.enumuration.transaction.OrderStatus.FAILED);
2475
                    }
25865 amit.gupta 2476
 
31697 amit.gupta 2477
                }
2478
                // LOGGER.info("payment" + payments);
25865 amit.gupta 2479
 
31697 amit.gupta 2480
            }
2481
        }
2482
    }
25865 amit.gupta 2483
 
31697 amit.gupta 2484
    public static class SaleTargetReportModel {
2485
        private double totalSale;
2486
        private long totalQty;
2487
        private double past3daysSale;
2488
        private int fofoId;
2489
        private String code;
31724 amit.gupta 2490
        private ActivationType activationType;
25865 amit.gupta 2491
 
31724 amit.gupta 2492
 
2493
        @Override
2494
        public boolean equals(Object o) {
2495
            if (this == o) return true;
2496
            if (o == null || getClass() != o.getClass()) return false;
2497
            SaleTargetReportModel that = (SaleTargetReportModel) o;
2498
            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;
2499
        }
2500
 
2501
        @Override
2502
        public int hashCode() {
2503
            return Objects.hash(totalSale, totalQty, past3daysSale, fofoId, code, activationType, secondary, smartphoneSale, smartphoneQty, insuranceSale, insruanceQty);
2504
        }
2505
 
2506
        public ActivationType getActivationType() {
2507
            return activationType;
2508
        }
2509
 
2510
        public void setActivationType(ActivationType activationType) {
2511
            this.activationType = activationType;
2512
        }
2513
 
31697 amit.gupta 2514
        public double getSecondary() {
2515
            return secondary;
2516
        }
25865 amit.gupta 2517
 
31697 amit.gupta 2518
        public void setSecondary(double secondary) {
2519
            this.secondary = secondary;
2520
        }
25865 amit.gupta 2521
 
31697 amit.gupta 2522
        private double secondary;
25865 amit.gupta 2523
 
31697 amit.gupta 2524
        public int getFofoId() {
2525
            return fofoId;
2526
        }
25865 amit.gupta 2527
 
31697 amit.gupta 2528
        @Override
2529
        public String toString() {
31886 tejbeer 2530
            return "SaleTargetReportModel{" + "totalSale=" + totalSale + ", totalQty=" + totalQty + ", past3daysSale=" + past3daysSale + ", fofoId=" + fofoId + ", code='" + code + '\'' + ", secondary=" + secondary + ", smartphoneSale=" + smartphoneSale + ", smartphoneQty=" + smartphoneQty + ", insuranceSale=" + insuranceSale + ", insruanceQty=" + insruanceQty + '}';
31697 amit.gupta 2531
        }
25865 amit.gupta 2532
 
31697 amit.gupta 2533
        public String getCode() {
2534
            return code;
2535
        }
25865 amit.gupta 2536
 
31697 amit.gupta 2537
        public void setCode(String code) {
2538
            this.code = code;
2539
        }
25865 amit.gupta 2540
 
31697 amit.gupta 2541
        public void setFofoId(int fofoId) {
2542
            this.fofoId = fofoId;
2543
        }
25872 tejbeer 2544
 
31697 amit.gupta 2545
        private double smartphoneSale;
2546
        private long smartphoneQty;
2547
        private double insuranceSale;
2548
        private long insruanceQty;
26945 amit.gupta 2549
 
31697 amit.gupta 2550
        public long getTotalQty() {
2551
            return totalQty;
2552
        }
30765 tejbeer 2553
 
31697 amit.gupta 2554
        public void setTotalQty(long totalQty) {
2555
            this.totalQty = totalQty;
2556
        }
2557
 
2558
        public double getPast3daysSale() {
2559
            return past3daysSale;
2560
        }
2561
 
2562
        public void setPast3daysSale(double past3daysSale) {
2563
            this.past3daysSale = past3daysSale;
2564
        }
2565
 
2566
        public double getTotalSale() {
2567
            return totalSale;
2568
        }
2569
 
2570
        public void setTotalSale(double totalSale) {
2571
            this.totalSale = totalSale;
2572
        }
2573
 
2574
        public double getSmartphoneSale() {
2575
            return smartphoneSale;
2576
        }
2577
 
2578
        public void setSmartphoneSale(double smartphoneSale) {
2579
            this.smartphoneSale = smartphoneSale;
2580
        }
2581
 
2582
        public long getSmartphoneQty() {
2583
            return smartphoneQty;
2584
        }
2585
 
2586
        public void setSmartphoneQty(long smartphoneQty) {
2587
            this.smartphoneQty = smartphoneQty;
2588
        }
2589
 
2590
        public double getInsuranceSale() {
2591
            return insuranceSale;
2592
        }
2593
 
2594
        public void setInsuranceSale(double insuranceSale) {
2595
            this.insuranceSale = insuranceSale;
2596
        }
2597
 
2598
        public long getInsruanceQty() {
2599
            return insruanceQty;
2600
        }
2601
 
2602
        public void setInsruanceQty(long insruanceQty) {
2603
            this.insruanceQty = insruanceQty;
2604
        }
2605
 
2606
    }
2607
 
32482 amit.gupta 2608
    private void getStateWiseSales
2609
            (Map<Integer, SaleTargetReportModel> saleTargetReportModelMap, Map<Integer, FofoReportingModel> partnerSalesHeadersMap) throws
2610
            Exception {
31697 amit.gupta 2611
        String timeString = "Today %s";
2612
        LocalDateTime now = LocalDateTime.now();
2613
 
2614
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("h:m a");
35521 amit 2615
        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);
31697 amit.gupta 2616
 
2617
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false);
2618
 
31746 amit.gupta 2619
        for (Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {
2620
            String email = storeGuyEntry.getKey();
2621
            Set<Integer> fofoIds = storeGuyEntry.getValue();
2622
            LOGGER.info("fofoIds {}", fofoIds);
24683 amit.gupta 2623
 
31746 amit.gupta 2624
            if (!fofoIds.isEmpty()) {
31886 tejbeer 2625
                List<FofoStore> stores = fofoStoreRepository.selectActivePartnersByRetailerIds(new ArrayList<>(fofoIds));
26945 amit.gupta 2626
 
31724 amit.gupta 2627
                Map<String, List<Integer>> stateMap = stores.stream().collect(groupingBy(
2628
                        x -> x.getCode().substring(0, 2), mapping(x -> x.getId(), Collectors.toList())));
31697 amit.gupta 2629
                List<List<Serializable>> stateWiseSales = new ArrayList<>();
33452 amit.gupta 2630
                for (Entry<String, List<Integer>> stateMapEntry : stateMap.entrySet()) {
31886 tejbeer 2631
                    long totalQty = stateMapEntry.getValue().stream().collect(Collectors.summingLong(x -> saleTargetReportModelMap.get(x).getTotalQty()));
2632
                    double totalSale = stateMapEntry.getValue().stream().collect(Collectors.summingDouble(x -> saleTargetReportModelMap.get(x).getTotalSale()));
2633
                    long smartPhoneQty = stateMapEntry.getValue().stream().collect(Collectors.summingLong(x -> saleTargetReportModelMap.get(x).getSmartphoneQty()));
31697 amit.gupta 2634
                    double smartPhoneSale = stateMapEntry.getValue().stream().collect(
2635
                            Collectors.summingDouble(x -> saleTargetReportModelMap.get(x).getSmartphoneSale()));
2636
                    stateWiseSales.add(
2637
                            Arrays.asList(stateMapEntry.getKey(), smartPhoneQty, smartPhoneSale, totalQty, totalSale));
2638
                }
2639
                StringBuilder sb = new StringBuilder();
2640
                sb.append("<html><body>");
2641
                sb.append("<p>Statewise Sale Report:</p><br/><table style=\"border-collapse: collapse;\">");
31886 tejbeer 2642
                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>");
31697 amit.gupta 2643
                for (List<Serializable> stateSale : stateWiseSales) {
2644
                    sb.append("<tr>");
2645
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + stateSale.get(0) + "</td>");
2646
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + stateSale.get(1) + "</td>");
2647
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + stateSale.get(2) + "</td>");
2648
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + stateSale.get(3) + "</td>");
2649
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + stateSale.get(4) + "</td>");
2650
                    sb.append("</tr>");
2651
                }
2652
                sb.append("</tbody></table><br><br>");
26945 amit.gupta 2653
 
31697 amit.gupta 2654
                sb.append("<p>Partnerwise Report:</p><br/><table style=\"border-collapse: collapse;\">");
31886 tejbeer 2655
                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>");
31169 tejbeer 2656
 
2657
 
31886 tejbeer 2658
                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());
31169 tejbeer 2659
 
31697 amit.gupta 2660
                String subject = String.format("Sale till %s", String.format(timeString, now.format(timeFormatter)));
31169 tejbeer 2661
 
31886 tejbeer 2662
                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");
31697 amit.gupta 2663
                List<List<?>> rows = new ArrayList<>();
2664
                for (Integer fofoId : sortedSaleTargetReport) {
2665
                    FofoReportingModel fofoReportingModel = partnerSalesHeadersMap.get(fofoId);
31886 tejbeer 2666
                    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()
31697 amit.gupta 2667
                    ));
31169 tejbeer 2668
 
31724 amit.gupta 2669
                    //Now try to populate html rows
2670
                    if (!saleTargetReportModelMap.get(fofoId).getActivationType().equals(ActivationType.ACTIVE)) {
31697 amit.gupta 2671
                        continue;
2672
                    }
2673
                    if (saleTargetReportModelMap.get(fofoId).getSecondary() == 0) {
2674
                        sb.append("<tr style='background-color:#D21F3C;color:white'>");
2675
                    } else {
2676
                        sb.append("<tr>");
2677
                    }
31886 tejbeer 2678
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + partnerSalesHeadersMap.get(fofoId).getCode() + "</td>");
2679
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + partnerSalesHeadersMap.get(fofoId).getBusinessName() + "</td>");
2680
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + partnerSalesHeadersMap.get(fofoId).getBusinessManager() + "</td>");
2681
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + partnerSalesHeadersMap.get(fofoId).getRegionalManager() + "</td>");
2682
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + partnerSalesHeadersMap.get(fofoId).getTerritoryManager() + "</td>");
2683
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + saleTargetReportModelMap.get(fofoId).getSecondary() + "</td>");
2684
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + saleTargetReportModelMap.get(fofoId).getTotalSale() + "</td>");
2685
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + saleTargetReportModelMap.get(fofoId).getSmartphoneSale() + "</td>");
2686
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + saleTargetReportModelMap.get(fofoId).getSmartphoneQty() + "</td>");
31697 amit.gupta 2687
                    sb.append("</tr>");
24841 govind 2688
 
25300 tejbeer 2689
 
31697 amit.gupta 2690
                }
2691
                sb.append("</tr>");
2692
                sb.append("</body></html>");
2693
                String statewiseSaleReport = sb.toString();
25300 tejbeer 2694
 
2695
 
31697 amit.gupta 2696
                ByteArrayOutputStream baos = null;
2697
                try {
2698
                    baos = FileUtil.getCSVByteStream(headers, rows);
2699
                } catch (Exception e2) {
2700
                    e2.printStackTrace();
2701
                }
2702
                Attachment attachment = new Attachment("PartnerSalePerformance.csv", new ByteArrayResource(baos.toByteArray()));
36460 ranu 2703
                Utils.sendHtmlMailWithAttachments(googleMailSender, new String[]{email}, null, "Statewise " + subject, statewiseSaleReport, attachment);
31697 amit.gupta 2704
            }
2705
        }
2706
    }
29668 tejbeer 2707
 
32350 amit.gupta 2708
 
32482 amit.gupta 2709
    private void sendMailOfHtmlFormat(JavaMailSender sender, String[] email, String body, String cc[], String subject) throws
2710
            MessagingException, ProfitMandiBusinessException, IOException {
32350 amit.gupta 2711
        MimeMessage message = sender.createMimeMessage();
31697 amit.gupta 2712
        MimeMessageHelper helper = new MimeMessageHelper(message);
2713
        helper.setSubject(subject);
2714
        helper.setText(body, true);
2715
        helper.setTo(email);
2716
        if (cc != null) {
2717
            helper.setCc(cc);
2718
        }
36463 ranu 2719
        InternetAddress senderAddress = new InternetAddress("sdtech@smartdukaan.com", "Smart Dukaan");
31697 amit.gupta 2720
        helper.setFrom(senderAddress);
36472 amit 2721
        sender.send(message);
31697 amit.gupta 2722
    }
25694 amit.gupta 2723
 
31697 amit.gupta 2724
    public void sendNotification() throws Exception {
34042 vikas.jang 2725
        LOGGER.info("FCM sendNotification");
36584 ranu 2726
        List<PushNotifications> pushNotifications = pushNotificationRepository.selectAllPendingNotifications();
31697 amit.gupta 2727
        if (!pushNotifications.isEmpty()) {
34042 vikas.jang 2728
            InputStream serviceAccount = getClass().getClassLoader().getResourceAsStream("service-account.json");
34039 vikas.jang 2729
            GoogleCredentials googleCredentials = GoogleCredentials.fromStream(serviceAccount).createScoped(FCM_SCOPED);
2730
            googleCredentials.refreshIfExpired();
2731
            String accessToken = googleCredentials.getAccessToken().getTokenValue();
2732
 
31697 amit.gupta 2733
            for (PushNotifications pushNotification : pushNotifications) {
2734
                Device device = deviceRepository.selectById(pushNotification.getDeviceId());
31886 tejbeer 2735
                NotificationCampaign notificationCampaign = notificationCampaignRepository.selectById(pushNotification.getNotificationCampaignid());
2736
                SimpleCampaignParams scp = gson.fromJson(notificationCampaign.getImplementationParams(), SimpleCampaignParams.class);
31697 amit.gupta 2737
                Campaign campaign = new SimpleCampaign(scp);
2738
                String result_url = campaign.getUrl() + "&user_id=" + device.getUser_id();
34039 vikas.jang 2739
 
2740
                JSONObject message = new JSONObject();
2741
                message.put("token", device.getFcmId());
2742
 
2743
                JSONObject notification = new JSONObject();
2744
                notification.put("title", campaign.getTitle());
2745
                notification.put("body", campaign.getMessage());
2746
                message.put("notification", notification);
2747
 
2748
                JSONObject data = new JSONObject();
2749
                data.put("type", campaign.getType());
2750
                data.put("url", result_url);
2751
                data.put("time_to_live", campaign.getExpireTimestamp());
2752
                data.put("image", campaign.getImageUrl());
2753
                data.put("largeIcon", "large_icon");
2754
                data.put("smallIcon", "small_icon");
34043 vikas.jang 2755
                data.put("vibrate", "1");
34044 vikas.jang 2756
                data.put("pid", String.valueOf(pushNotification.getId()));
34043 vikas.jang 2757
                data.put("sound", "1");
34039 vikas.jang 2758
                data.put("priority", "high");
2759
                message.put("data", data);
2760
 
2761
                JSONObject payload = new JSONObject();
2762
                payload.put("message", message);
2763
 
31697 amit.gupta 2764
                try {
36420 amit 2765
                    CloseableHttpClient client = HttpClientFactory.apacheHttp();
31697 amit.gupta 2766
                    HttpPost httpPost = new HttpPost(FCM_URL);
25694 amit.gupta 2767
 
34039 vikas.jang 2768
                    httpPost.setHeader("Authorization", "Bearer " + accessToken);
2769
                    httpPost.setHeader("Content-Type", "application/json");
2770
 
2771
                    StringEntity entity = new StringEntity(payload.toString());
31697 amit.gupta 2772
                    httpPost.setEntity(entity);
2773
                    CloseableHttpResponse response = client.execute(httpPost);
34275 tejus.loha 2774
                    LOGGER.info("google FCM status code: {}", response.getStatusLine().getStatusCode());
34043 vikas.jang 2775
                    String responseBody = new BufferedReader(new InputStreamReader(response.getEntity().getContent()))
2776
                            .lines().collect(Collectors.joining("\n"));
31697 amit.gupta 2777
                    if (response.getStatusLine().getStatusCode() == 200) {
2778
                        pushNotification.setSentTimestamp(LocalDateTime.now());
2779
                    } else {
2780
                        pushNotification.setSentTimestamp(LocalDateTime.of(1970, 1, 1, 00, 00));
34043 vikas.jang 2781
                        LOGGER.info("FCM Response message" + responseBody);
31697 amit.gupta 2782
                        response.toString();
2783
                    }
25694 amit.gupta 2784
 
31697 amit.gupta 2785
                } catch (Exception e) {
2786
                    e.printStackTrace();
2787
                    pushNotification.setSentTimestamp(LocalDateTime.of(1970, 1, 1, 00, 00));
2788
                    LOGGER.info("message " + "not sent " + e.getMessage());
2789
                }
2790
            }
2791
        }
2792
    }
25721 tejbeer 2793
 
31697 amit.gupta 2794
    public void grouping() throws Exception {
2795
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-yyyy hh:mm");
2796
        List<PriceDropIMEI> priceDropImeis = priceDropIMEIRepository.selectByStatus(PriceDropImeiStatus.APPROVED);
31886 tejbeer 2797
        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")));
31697 amit.gupta 2798
        Map<Integer, CustomRetailer> retailersMap = retailerService.getFofoRetailers(false);
2799
        for (PriceDropIMEI priceDropIMEI : priceDropImeis) {
2800
            if (priceDropIMEI.getPartnerId() == 0)
2801
                continue;
2802
            HashSet<String> imeis = new HashSet<>();
2803
            PriceDrop priceDrop = priceDropRepository.selectById(priceDropIMEI.getPriceDropId());
2804
            imeis.add(priceDropIMEI.getImei());
31886 tejbeer 2805
            List<InventoryItem> inventoryItems = inventoryItemRepository.selectByFofoIdSerialNumbers(priceDropIMEI.getPartnerId(), imeis, false);
31697 amit.gupta 2806
            if (inventoryItems.size() == 0) {
2807
                LOGGER.info("Need to investigate partnerId - {} imeis - {}", priceDropIMEI.getPartnerId(), imeis);
2808
                continue;
2809
            }
2810
            InventoryItem inventoryItem = inventoryItems.get(0);
2811
            CustomRetailer customRetailer = retailersMap.get(inventoryItem.getFofoId());
31886 tejbeer 2812
            if (inventoryItem.getLastScanType().equals(ScanType.DOA_OUT) || inventoryItem.getLastScanType().equals(ScanType.PURCHASE_RET)) {
31697 amit.gupta 2813
                // check if pricedrop has been rolled out
31886 tejbeer 2814
                List<UserWalletHistory> uwh = walletService.getAllByReference(inventoryItem.getFofoId(), priceDropIMEI.getPriceDropId(), WalletReferenceType.PRICE_DROP);
31697 amit.gupta 2815
                if (uwh.size() > 0) {
2816
                    Item item = itemRepository.selectById(inventoryItem.getItemId());
31886 tejbeer 2817
                    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) + "")));
31697 amit.gupta 2818
                }
2819
            }
2820
        }
2821
    }
25721 tejbeer 2822
 
31697 amit.gupta 2823
    public void toffeeRollback() throws Exception {
2824
        toffeeService.cancelPolicyCopy("110143521986");
2825
        toffeeService.getOrderId("110143521986");
2826
    }
27212 tejbeer 2827
 
31697 amit.gupta 2828
    public void attachToffeeInvoices() throws Exception {
31886 tejbeer 2829
        List<InsurancePolicy> insurancePolicies = insurancePolicyRepository.selectAllByProviderId(3, Optional.of(false));
31697 amit.gupta 2830
        for (InsurancePolicy insurancePolicy : insurancePolicies) {
2831
            String invoiceNumber = insurancePolicy.getInvoiceNumber();
2832
            FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
37058 amit 2833
            com.spice.profitmandi.common.model.InvoicePdfModel pdfModel = orderService.getInvoicePdfModel(fofoOrder.getId());
31697 amit.gupta 2834
            java.io.ByteArrayOutputStream byteArrayOutputStream = new java.io.ByteArrayOutputStream();
2835
            PdfUtils.generateAndWrite(Arrays.asList(pdfModel), byteArrayOutputStream);
31886 tejbeer 2836
            String pdfInvoiceString = "data:application/pdf;base64," + Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
2837
            boolean attached = toffeeService.attachInvoice(insurancePolicy.getPolicyNumber().split("#")[1], pdfInvoiceString);
31697 amit.gupta 2838
            if (attached) {
2839
                insurancePolicy.setPosted(true);
2840
            }
2841
        }
2842
    }
25721 tejbeer 2843
 
31697 amit.gupta 2844
    public void sendBAGPendingPolicies() throws Exception {
31886 tejbeer 2845
        List<InsurancePolicy> insurancePolicies = insurancePolicyRepository.selectAllByProviderId(4, Optional.of(false));
31697 amit.gupta 2846
        for (InsurancePolicy insurancePolicy : insurancePolicies) {
2847
            String invoiceNumber = insurancePolicy.getInvoiceNumber();
2848
            FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
2849
            FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId()).get(0);
2850
            CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());
2851
            Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
2852
            BAGInsuranceModel bagInsuranceModel = new BAGInsuranceModel();
2853
            // bagInsuranceModel.setModelId();
2854
            bagInsuranceModel.setAddressLine1(customerAddress.getLine1());
2855
            bagInsuranceModel.setAddressLine2(customerAddress.getLine2());
2856
            bagInsuranceModel.setCity(customerAddress.getCity());
2857
            bagInsuranceModel.setBrandWarranty("1 Year");
2858
            Item item = itemRepository.selectById(fofoOrderItem.getId());
2859
            bagInsuranceModel.setModelName(item.getItemDescription());
2860
            bagInsuranceModel.setDateOfPurchase(fofoOrder.getFormattedDate());
2861
            bagInsuranceModel.setEmail(customer.getEmailId());
2862
            bagInsuranceModel.setImei1(insurancePolicy.getSerialNumber());
2863
            bagInsuranceModel.setFirstName(customer.getFirstName());
2864
            bagInsuranceModel.setLastName(customer.getLastName());
2865
            bagInsuranceModel.setMobileNumber(customer.getMobileNumber());
2866
            bagInsuranceModel.setPlanId("");
2867
            insurancePolicy.setPosted(true);
2868
        }
2869
    }
25721 tejbeer 2870
 
31697 amit.gupta 2871
    public void schemeRollback(List<String> schemeIds) throws Exception {
2872
        List<Integer> schemeIdsInt = schemeIds.stream().map(x -> Integer.parseInt(x)).collect(Collectors.toList());
31886 tejbeer 2873
        Map<Integer, Scheme> schemesMap = schemeRepository.selectBySchemeIds(schemeIdsInt, 0, schemeIds.size()).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
31697 amit.gupta 2874
        List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectBySchemeIds(new HashSet<>(schemeIdsInt));
2875
        for (SchemeInOut sio : schemeInOuts) {
2876
            Scheme scheme = schemesMap.get(sio.getSchemeId());
34324 amit.gupta 2877
            if (scheme.getType().getTransactionType().equals(StockTransactionType.IN)) {
25721 tejbeer 2878
 
34324 amit.gupta 2879
            } else if (scheme.getType().getTransactionType().equals(StockTransactionType.OUT)) {
31697 amit.gupta 2880
                InventoryItem inventoryItem = inventoryItemRepository.selectById(sio.getInventoryItemId());
2881
                List<ScanRecord> sr = scanRecordRepository.selectByInventoryItemId(sio.getInventoryItemId());
31886 tejbeer 2882
                ScanRecord scanRecord = sr.stream().filter(x -> x.getType().equals(ScanType.SALE)).max((x1, x2) -> x1.getCreateTimestamp().compareTo(x2.getCreateTimestamp())).get();
2883
                if (scanRecord.getCreateTimestamp().isAfter(scheme.getEndDateTime()) || scanRecord.getCreateTimestamp().isBefore(scheme.getStartDateTime())) {
31697 amit.gupta 2884
                    sio.setRolledBackTimestamp(LocalDateTime.now());
2885
                    FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(scanRecord.getOrderId());
31886 tejbeer 2886
                    String rollbackReason = "Scheme reversed for " + itemRepository.selectById(inventoryItem.getItemId()).getItemDescription() + "/Inv - " + fofoOrder.getInvoiceNumber();
2887
                    walletService.rollbackAmountFromWallet(scanRecord.getFofoId(), sio.getAmount(), scanRecord.getOrderId(), WalletReferenceType.SCHEME_OUT, rollbackReason, LocalDateTime.now());
2888
                    System.out.printf("Amount %f,SchemeId %d,Reason %s\n", sio.getAmount(), sio.getSchemeId(), rollbackReason);
31697 amit.gupta 2889
                }
2890
            }
2891
        }
2892
        // throw new Exception();
2893
    }
25721 tejbeer 2894
 
31697 amit.gupta 2895
    public void checkfocusedModelInPartnerStock() throws Exception {
25721 tejbeer 2896
 
35442 amit 2897
        // ========== PHASE 1: Batch fetch all data upfront ==========
2898
        Map<Integer, FofoStore> fofoStoreMap = fofoStoreRepository.selectActiveStores().stream()
2899
                .collect(Collectors.toMap(FofoStore::getId, x -> x));
2900
        List<Integer> allPartnerIds = new ArrayList<>(fofoStoreMap.keySet());
2901
 
31886 tejbeer 2902
        Map<Integer, Map<Integer, List<SaholicCIS>>> warehouseItemAvailabilityMap = saholicInventoryService.getSaholicStock();
31697 amit.gupta 2903
        Map<Integer, String> warehouseMap = ProfitMandiConstants.WAREHOUSE_MAP;
2904
        Map<Integer, FofoReportingModel> partnerIdSalesHeadersMap = this.getPartnerIdSalesHeaders();
35442 amit 2905
        Map<Integer, List<FocusedModel>> regionFocusedModelsMap = focusedModelRepository.selectAll().stream()
2906
                .collect(Collectors.groupingBy(FocusedModel::getRegionId));
2907
        LOGGER.info("regionFocusedModelsMap - {}", regionFocusedModelsMap);
31886 tejbeer 2908
        Map<Integer, Map<Integer, List<SaholicPOItem>>> warehousePoItemAvailabilityMap = saholicInventoryService.getSaholicPOItems();
35442 amit 2909
 
2910
        // Batch fetch all customRetailers upfront
2911
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(allPartnerIds);
2912
        LOGGER.info("Fetched {} customRetailers", customRetailerMap.size());
2913
 
2914
        // Batch fetch all inventory snapshots upfront
2915
        Map<Integer, List<CurrentInventorySnapshot>> allInventorySnapshotsMap = currentInventorySnapshotRepository
2916
                .selectByFofoId(allPartnerIds).stream()
2917
                .collect(Collectors.groupingBy(CurrentInventorySnapshot::getFofoId));
2918
        LOGGER.info("Fetched inventory snapshots for {} partners", allInventorySnapshotsMap.size());
2919
 
2920
        // Batch fetch all pending GRN orders upfront
2921
        Map<Integer, List<Order>> allGrnPendingOrdersMap = orderRepository.selectPendingGrnOrders(allPartnerIds).stream()
2922
                .collect(Collectors.groupingBy(Order::getRetailerId));
2923
        LOGGER.info("Fetched GRN pending orders for {} partners", allGrnPendingOrdersMap.size());
2924
 
2925
        // Batch fetch all processing orders upfront
2926
        Map<Integer, List<Order>> allProcessingOrdersMap = orderRepository.selectOrders(allPartnerIds, orderStatusList).stream()
2927
                .collect(Collectors.groupingBy(Order::getRetailerId));
2928
        LOGGER.info("Fetched processing orders for {} partners", allProcessingOrdersMap.size());
2929
 
2930
        // Collect all focused catalog IDs
2931
        Set<Integer> allFocusedCatalogIds = regionFocusedModelsMap.values().stream()
2932
                .flatMap(List::stream)
2933
                .map(FocusedModel::getCatalogId)
2934
                .collect(Collectors.toSet());
2935
 
2936
        // Batch fetch all items by catalog IDs upfront
35446 amit 2937
        List<Item> allItemsByCatalogId = itemRepository.selectAllByCatalogIds(allFocusedCatalogIds);
2938
        Map<Integer, List<Item>> itemsByCatalogIdMap = allItemsByCatalogId.stream()
35442 amit 2939
                .collect(Collectors.groupingBy(Item::getCatalogItemId));
2940
        LOGGER.info("Fetched items for {} catalog IDs", itemsByCatalogIdMap.size());
2941
 
35446 amit 2942
        // Batch fetch all tagListings using pre-fetched items to avoid duplicate item fetch
35442 amit 2943
        Map<Integer, TagListing> tagListingByCatalogIdMap = tagListingRepository
35446 amit 2944
                .selectAllByItems(allItemsByCatalogId);
35442 amit 2945
        LOGGER.info("Fetched {} tagListings", tagListingByCatalogIdMap.size());
2946
 
36680 amit 2947
        // Collect all distinct brands from focused models
2948
        Set<String> allFocusedBrands = new HashSet<>();
2949
        for (List<Item> itemList : itemsByCatalogIdMap.values()) {
2950
            if (itemList != null && !itemList.isEmpty() && allFocusedCatalogIds.contains(itemList.get(0).getCatalogItemId())) {
2951
                allFocusedBrands.add(itemList.get(0).getBrand());
2952
            }
2953
        }
2954
        LOGGER.info("Focused model brands: {}", allFocusedBrands);
2955
 
2956
        // Batch fetch: which focused brands each partner had in stock in the past 30 days
2957
        LocalDateTime monthStart = LocalDateTime.now().minusDays(30).withHour(0).withMinute(0).withSecond(0).withNano(0);
2958
 
2959
        Map<Integer, Set<String>> partnerBrandsFromInventory = !allFocusedBrands.isEmpty()
2960
                ? inventoryItemRepository.selectDistinctBrandsByFofoIds(allPartnerIds, allFocusedBrands, monthStart)
2961
                : new HashMap<>();
2962
 
2963
        Map<Integer, Set<String>> partnerBrandsFromScans = !allFocusedBrands.isEmpty()
2964
                ? scanRecordRepository.selectDistinctBrandsByFofoIds(allPartnerIds, allFocusedBrands, monthStart)
2965
                : new HashMap<>();
2966
 
2967
        // Merge both sources into a single map
2968
        Map<Integer, Set<String>> partnerBrandsMap = new HashMap<>(partnerBrandsFromInventory);
2969
        for (Map.Entry<Integer, Set<String>> entry : partnerBrandsFromScans.entrySet()) {
2970
            partnerBrandsMap.computeIfAbsent(entry.getKey(), k -> new HashSet<>()).addAll(entry.getValue());
2971
        }
2972
        LOGGER.info("Built partnerBrandsMap for {} partners", partnerBrandsMap.size());
2973
 
35442 amit 2974
        // Collect all item IDs from inventory, GRN orders, and processing orders for batch item lookup
2975
        Set<Integer> allItemIds = new HashSet<>();
2976
        allInventorySnapshotsMap.values().forEach(list ->
2977
                list.forEach(cis -> allItemIds.add(cis.getItemId())));
2978
        allGrnPendingOrdersMap.values().forEach(orders ->
2979
                orders.forEach(o -> allItemIds.add(o.getLineItem().getItemId())));
2980
        allProcessingOrdersMap.values().forEach(orders ->
2981
                orders.forEach(o -> allItemIds.add(o.getLineItem().getItemId())));
2982
 
2983
        // Batch fetch all items and create itemId -> catalogId mapping
2984
        Map<Integer, Integer> itemIdToCatalogIdMap = new HashMap<>();
2985
        if (!allItemIds.isEmpty()) {
2986
            itemRepository.selectByIds(allItemIds).forEach(item ->
2987
                    itemIdToCatalogIdMap.put(item.getId(), item.getCatalogItemId()));
2988
        }
2989
        LOGGER.info("Built itemId->catalogId mapping for {} items", itemIdToCatalogIdMap.size());
2990
 
2991
        // ========== PHASE 2: Build partner region mappings ==========
34352 amit.gupta 2992
        Map<Integer, Set<Integer>> partnerToRegions = partnerRegionRepository.selectAll().stream()
2993
                .collect(Collectors.groupingBy(
2994
                        pr -> pr.getFofoId(),
2995
                        Collectors.mapping(pr -> pr.getRegionId(), Collectors.toSet())
2996
                ));
2997
        Map<Set<Integer>, List<Integer>> regionPartnerMap = partnerToRegions.entrySet().stream()
2998
                .collect(Collectors.groupingBy(
2999
                        Map.Entry::getValue,
3000
                        Collectors.mapping(Map.Entry::getKey, Collectors.toList())
3001
                ));
35442 amit 3002
        LOGGER.info("regionPartnerMap - {}", regionPartnerMap.keySet());
3003
 
3004
        // ========== PHASE 3: Process partners using pre-fetched data ==========
3005
        Map<Integer, List<FocusedModelShortageModel>> focusedModelShortageReportMap = new HashMap<>();
3006
 
34352 amit.gupta 3007
        for (Map.Entry<Set<Integer>, List<Integer>> regionPartnerEntry : regionPartnerMap.entrySet()) {
3008
            Set<Integer> regionIds = regionPartnerEntry.getKey();
35442 amit 3009
            List<Integer> partnerIds = new ArrayList<>(regionPartnerEntry.getValue());
3010
 
34502 amit.gupta 3011
            if (regionIds.stream().anyMatch(x -> !regionFocusedModelsMap.containsKey(x))) continue;
34383 amit.gupta 3012
 
35442 amit 3013
            LOGGER.info("Processing regionIds: {}", regionIds);
3014
            if (regionIds == null || regionIds.isEmpty()) {
34352 amit.gupta 3015
                LOGGER.info("No region found for partner {}", partnerIds);
34343 amit.gupta 3016
                continue;
3017
            }
34502 amit.gupta 3018
            if (regionIds.contains(5)) {
34383 amit.gupta 3019
                partnerIds.addAll(fofoStoreMap.keySet());
3020
            }
35442 amit 3021
 
3022
            Map<Integer, Optional<Integer>> focusedCatalogIdAndQtyMap = regionIds.stream()
3023
                    .map(regionFocusedModelsMap::get)
3024
                    .flatMap(x -> x != null ? x.stream() : Stream.empty())
3025
                    .collect(groupingBy(FocusedModel::getCatalogId,
3026
                            mapping(FocusedModel::getObsMinimumQty, Collectors.maxBy(Integer::compareTo))));
3027
 
3028
            if (focusedCatalogIdAndQtyMap.isEmpty()) continue;
3029
 
34352 amit.gupta 3030
            for (int partnerId : partnerIds) {
34502 amit.gupta 3031
                if (partnerId == 0) continue;
34352 amit.gupta 3032
                FofoStore fofoStore = fofoStoreMap.get(partnerId);
35442 amit 3033
                if (fofoStore == null) continue;
3034
 
3035
                CustomRetailer customRetailer = customRetailerMap.get(partnerId);
3036
                if (customRetailer == null) continue;
3037
 
34352 amit.gupta 3038
                List<FocusedModelShortageModel> focusedModelShortageList = new ArrayList<>();
3039
                focusedModelShortageReportMap.put(fofoStore.getId(), focusedModelShortageList);
34343 amit.gupta 3040
 
35442 amit 3041
                // Build catalogIdAndQtyMap from pre-fetched inventory snapshots
3042
                Map<Integer, Integer> catalogIdAndQtyMap = new HashMap<>();
3043
                List<CurrentInventorySnapshot> inventorySnapshots = allInventorySnapshotsMap.get(partnerId);
3044
                if (inventorySnapshots != null) {
3045
                    Map<Integer, Integer> itemQtyMap = inventorySnapshots.stream()
3046
                            .collect(Collectors.toMap(CurrentInventorySnapshot::getItemId, CurrentInventorySnapshot::getAvailability));
3047
                    for (Map.Entry<Integer, Integer> e : itemQtyMap.entrySet()) {
3048
                        Integer catalogId = itemIdToCatalogIdMap.get(e.getKey());
3049
                        if (catalogId != null) {
3050
                            catalogIdAndQtyMap.merge(catalogId, e.getValue(), Integer::sum);
3051
                        }
3052
                    }
34352 amit.gupta 3053
                }
25721 tejbeer 3054
 
35442 amit 3055
                // Build grnPendingOrdersMap from pre-fetched orders
3056
                Map<Integer, Integer> grnPendingOrdersMap = new HashMap<>();
3057
                List<Order> grnOrders = allGrnPendingOrdersMap.get(partnerId);
3058
                if (grnOrders != null) {
3059
                    for (Order order : grnOrders) {
3060
                        Integer catalogId = itemIdToCatalogIdMap.get(order.getLineItem().getItemId());
3061
                        if (catalogId != null) {
3062
                            grnPendingOrdersMap.merge(catalogId, order.getLineItem().getQuantity(), Integer::sum);
3063
                        }
3064
                    }
34352 amit.gupta 3065
                }
25800 tejbeer 3066
 
35442 amit 3067
                // Build processingOrderMap from pre-fetched orders
3068
                Map<Integer, Integer> processingOrderMap = new HashMap<>();
3069
                List<Order> processingOrders = allProcessingOrdersMap.get(partnerId);
3070
                if (processingOrders != null) {
3071
                    for (Order order : processingOrders) {
3072
                        Integer catalogId = itemIdToCatalogIdMap.get(order.getLineItem().getItemId());
3073
                        if (catalogId != null) {
3074
                            processingOrderMap.merge(catalogId, order.getLineItem().getQuantity(), Integer::sum);
3075
                        }
3076
                    }
34352 amit.gupta 3077
                }
25721 tejbeer 3078
 
35442 amit 3079
                Map<Integer, List<SaholicCIS>> itemAvailabilityMap = warehouseItemAvailabilityMap.get(fofoStore.getWarehouseId());
3080
                Map<Integer, List<SaholicPOItem>> poItemAvailabilityMap = warehousePoItemAvailabilityMap.get(fofoStore.getWarehouseId());
25721 tejbeer 3081
 
34352 amit.gupta 3082
                for (Entry<Integer, Optional<Integer>> entry : focusedCatalogIdAndQtyMap.entrySet()) {
35442 amit 3083
                    int catalogId = entry.getKey();
3084
                    int minQty = entry.getValue().orElse(0);
3085
                    int inStockQty = catalogIdAndQtyMap.getOrDefault(catalogId, 0);
3086
                    int processingQty = processingOrderMap.getOrDefault(catalogId, 0);
3087
                    int grnPendingQty = grnPendingOrdersMap.getOrDefault(catalogId, 0);
28526 tejbeer 3088
 
34352 amit.gupta 3089
                    int grnStockQty = grnPendingQty + inStockQty;
3090
                    int totalQty = processingQty + grnPendingQty + inStockQty;
3091
                    int shortageQty = minQty - totalQty;
27213 tejbeer 3092
 
35442 amit 3093
                    // Use pre-fetched items
3094
                    List<Item> items = itemsByCatalogIdMap.get(catalogId);
3095
                    if (items == null || items.isEmpty()) continue;
25721 tejbeer 3096
 
35442 amit 3097
                    // Use pre-fetched tagListing
3098
                    TagListing tagListing = tagListingByCatalogIdMap.get(catalogId);
3099
                    if (tagListing == null) continue;
27208 tejbeer 3100
 
36680 amit 3101
                    // Skip if partner didn't carry this brand at any point this month
3102
                    String brand = items.get(0).getBrand();
3103
                    if (!partnerBrandsMap.getOrDefault(partnerId, Collections.emptySet()).contains(brand)) continue;
3104
 
35442 amit 3105
                    int allColorNetAvailability = 0;
3106
                    int allColorPoAvailability = 0;
28528 tejbeer 3107
 
34352 amit.gupta 3108
                    for (Item item : items) {
3109
                        if (itemAvailabilityMap != null) {
35442 amit 3110
                            List<SaholicCIS> currentAvailability = itemAvailabilityMap.get(item.getId());
3111
                            if (currentAvailability != null) {
3112
                                allColorNetAvailability += currentAvailability.stream()
3113
                                        .mapToInt(SaholicCIS::getNetavailability).sum();
3114
                            }
34352 amit.gupta 3115
                        }
3116
                        if (poItemAvailabilityMap != null) {
35442 amit 3117
                            List<SaholicPOItem> poItemAvailability = poItemAvailabilityMap.get(item.getId());
3118
                            if (poItemAvailability != null) {
3119
                                allColorPoAvailability += poItemAvailability.stream()
3120
                                        .mapToInt(SaholicPOItem::getUnfulfilledQty).sum();
3121
                            }
34352 amit.gupta 3122
                        }
31697 amit.gupta 3123
                    }
25721 tejbeer 3124
 
34352 amit.gupta 3125
                    FocusedModelShortageModel fm = new FocusedModelShortageModel();
3126
                    fm.setFofoId(fofoStore.getId());
3127
                    fm.setStoreCode(fofoStore.getCode());
3128
                    fm.setStoreName(customRetailer.getBusinessName());
3129
                    fm.setBrandName(items.get(0).getBrand());
3130
                    fm.setModelName(items.get(0).getModelName());
3131
                    fm.setModelNumber(items.get(0).getModelNumber());
3132
                    fm.setGrnStockQty(grnStockQty);
3133
                    fm.setPendingIndentQty(processingQty);
3134
                    fm.setShortageQty(shortageQty);
3135
                    fm.setPoAvailability(allColorPoAvailability);
3136
                    fm.setDp(tagListing.getSellingPrice());
3137
                    fm.setWarehouseName(warehouseMap.get(customRetailer.getWarehouseId()));
35442 amit 3138
 
3139
                    // FIX: Use fofoStore.getId() instead of fofoStore object as key
3140
                    FofoReportingModel reportingModel = partnerIdSalesHeadersMap.get(fofoStore.getId());
3141
                    if (reportingModel != null) {
3142
                        fm.setStateManager(reportingModel.getRegionalManager());
3143
                        fm.setTerritoryManager(reportingModel.getTerritoryManager());
34352 amit.gupta 3144
                    } else {
3145
                        fm.setStateManager("");
3146
                        fm.setTerritoryManager("");
31697 amit.gupta 3147
                    }
25800 tejbeer 3148
 
34352 amit.gupta 3149
                    fm.setItemName(items.get(0).getBrand() + items.get(0).getModelNumber() + items.get(0).getModelName());
3150
                    fm.setAvailability(allColorNetAvailability);
25800 tejbeer 3151
 
34352 amit.gupta 3152
                    focusedModelShortageList.add(fm);
31697 amit.gupta 3153
                }
3154
            }
34352 amit.gupta 3155
        }
25721 tejbeer 3156
 
35442 amit 3157
        // ========== PHASE 4: Send emails ==========
3158
        LOGGER.info("focusedModelShortageReportMap size: {}", focusedModelShortageReportMap.size());
31697 amit.gupta 3159
        if (!focusedModelShortageReportMap.isEmpty()) {
3160
            String fileName = "Stock Alert-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv";
3161
            Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
3162
            Map<String, List<List<?>>> emailRowsMap = new HashMap<>();
28526 tejbeer 3163
 
35442 amit 3164
            for (Map.Entry<Integer, List<FocusedModelShortageModel>> x : focusedModelShortageReportMap.entrySet()) {
3165
                for (Map.Entry<String, Set<Integer>> y : storeGuyMap.entrySet()) {
3166
                    if (y.getValue().contains(x.getKey())) {
3167
                        emailRowsMap.computeIfAbsent(y.getKey(), k -> new ArrayList<>());
3168
                        List<List<? extends Serializable>> fms = x.getValue().stream()
3169
                                .map(r -> Arrays.asList(r.getStoreCode(), r.getStoreName(), r.getBrandName(),
3170
                                        r.getModelName(), r.getModelNumber(), r.getDp(), r.getWarehouseName(),
3171
                                        r.getStateManager(), r.getTerritoryManager(), r.getPendingIndentQty(),
3172
                                        r.getGrnStockQty(), r.getShortageQty(), r.getAvailability()))
3173
                                .collect(Collectors.toList());
3174
                        emailRowsMap.get(y.getKey()).addAll(fms);
3175
                    }
31697 amit.gupta 3176
                }
35442 amit 3177
            }
25721 tejbeer 3178
 
35442 amit 3179
            List<String> headers = Arrays.asList("Store Code", "Store Name", "Brand", "Model Name", "Model Number",
3180
                    "DP", "Warehouse Name", "State Manager", "Territory Manager", "Pending Indent", "InStock",
3181
                    "Shortage Qty", "Availability");
25721 tejbeer 3182
 
35442 amit 3183
            for (Map.Entry<String, List<List<?>>> entry : emailRowsMap.entrySet()) {
31697 amit.gupta 3184
                try {
35442 amit 3185
                    ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, entry.getValue());
3186
                    String[] sendToArray = new String[]{entry.getKey()};
36460 ranu 3187
                    Utils.sendMailWithAttachment(googleMailSender, sendToArray, null, "Stock Alert", "PFA",
35442 amit 3188
                            fileName, new ByteArrayResource(baos.toByteArray()));
3189
                } catch (Exception e) {
3190
                    LOGGER.error("Failed to send email to {}", entry.getKey(), e);
31697 amit.gupta 3191
                }
35442 amit 3192
            }
31697 amit.gupta 3193
        }
3194
    }
25721 tejbeer 3195
 
31697 amit.gupta 3196
    private String getNotificationMessage(List<FocusedModelShortageModel> focusedModelShortageModel) {
3197
        StringBuilder sb = new StringBuilder();
3198
        sb.append("Focused Model Shortage in Your Stock : \n");
3199
        for (FocusedModelShortageModel entry : focusedModelShortageModel) {
25721 tejbeer 3200
 
31697 amit.gupta 3201
            sb.append(entry.getItemName() + "-" + entry.getShortageQty());
3202
            sb.append(String.format("%n", ""));
3203
        }
3204
        return sb.toString();
3205
    }
25721 tejbeer 3206
 
31697 amit.gupta 3207
    private void sendMailWithAttachments(String subject, String messageText, String email) throws Exception {
36402 amit 3208
        MimeMessage message = gmailRelaySender.createMimeMessage();
31697 amit.gupta 3209
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
25721 tejbeer 3210
 
31697 amit.gupta 3211
        helper.setSubject(subject);
3212
        helper.setText(messageText, true);
3213
        helper.setTo(email);
3214
        InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");
3215
        helper.setFrom(senderAddress);
36402 amit 3216
        gmailRelaySender.send(message);
25721 tejbeer 3217
 
31697 amit.gupta 3218
    }
25721 tejbeer 3219
 
31697 amit.gupta 3220
    private String getMessage(List<FocusedModelShortageModel> focusedModelShortageModel) {
3221
        StringBuilder sb = new StringBuilder();
31886 tejbeer 3222
        sb.append("<html><body><p>Alert</p><p>Focused Model Shortage in Your Stock:-</p>" + "<br/><table style='border:1px solid black ;padding: 5px';>");
3223
        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>");
31697 amit.gupta 3224
        for (FocusedModelShortageModel entry : focusedModelShortageModel) {
25721 tejbeer 3225
 
31697 amit.gupta 3226
            sb.append("<tr>");
3227
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getItemName() + "</td>");
25936 amit.gupta 3228
 
31697 amit.gupta 3229
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getShortageQty() + "</td>");
26790 tejbeer 3230
 
31697 amit.gupta 3231
            sb.append("</tr>");
25927 amit.gupta 3232
 
31697 amit.gupta 3233
        }
26790 tejbeer 3234
 
31697 amit.gupta 3235
        sb.append("</tbody></table></body></html>");
26945 amit.gupta 3236
 
31697 amit.gupta 3237
        return sb.toString();
3238
    }
26945 amit.gupta 3239
 
31697 amit.gupta 3240
    public void notifyLead() throws Exception {
31886 tejbeer 3241
        List<Lead> leadsToNotify = leadRepository.selectLeadsScheduledBetweenDate(null, LocalDateTime.now().minusDays(15), LocalDateTime.now().plusHours(4));
3242
        Map<Integer, String> authUserEmailMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getEmailId()));
31697 amit.gupta 3243
        LOGGER.info("authUserEmailMap {}", authUserEmailMap);
31886 tejbeer 3244
        Map<String, Integer> dtrEmailMap = dtrUserRepository.selectAllByEmailIds(new ArrayList<>(authUserEmailMap.values())).stream().collect(Collectors.toMap(x -> x.getEmailId(), x -> x.getId()));
25982 amit.gupta 3245
 
31697 amit.gupta 3246
        LOGGER.info("dtrEmailMap {}", dtrEmailMap);
26283 tejbeer 3247
 
31697 amit.gupta 3248
        Map<Integer, Integer> authUserKeyMap = new HashMap<>();
26283 tejbeer 3249
 
33452 amit.gupta 3250
        for (Entry<Integer, String> authUserEmail : authUserEmailMap.entrySet()) {
31697 amit.gupta 3251
            int authId = authUserEmail.getKey();
3252
            String email = authUserEmail.getValue();
3253
            authUserKeyMap.put(authId, dtrEmailMap.get(email));
3254
        }
3255
        LOGGER.info("authUserKeyMap", authUserKeyMap);
3256
        LOGGER.info("leadsToNotify {}", leadsToNotify);
26283 tejbeer 3257
 
31697 amit.gupta 3258
        String templateMessage = "Lead followup for %s %s, %s, %s is due by %s";
3259
        for (Lead lead : leadsToNotify) {
3260
            if (authUserKeyMap.get(lead.getAssignTo()) == null) {
3261
                LOGGER.info("Assignee no longer part of system {}", lead.getAssignTo());
3262
                continue;
3263
            }
3264
            String title = "Leads followup Reminder";
31886 tejbeer 3265
            String notificationMessage = String.format(templateMessage, lead.getFirstName(), lead.getLastName(), lead.getAddress(), lead.getLeadMobile(), leadTimeFormatter.format(lead.getScheduledTimestamp()));
31697 amit.gupta 3266
            String url = "https://app.smartdukaan.com/pages/home/leadUpdate?leadId=" + lead.getId();
3267
            SendNotificationModel sendNotificationModel = new SendNotificationModel();
3268
            sendNotificationModel.setCampaignName("Lead Reminder");
3269
            sendNotificationModel.setTitle(title);
3270
            sendNotificationModel.setMessage(notificationMessage);
3271
            sendNotificationModel.setType("url");
3272
            sendNotificationModel.setUrl(url);
3273
            sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(2));
3274
            sendNotificationModel.setMessageType(MessageType.reminder);
3275
            sendNotificationModel.setUserIds(Arrays.asList(authUserKeyMap.get(lead.getAssignTo())));
3276
            System.out.println(sendNotificationModel);
3277
            notificationService.sendNotification(sendNotificationModel);
3278
        }
3279
    }
26790 tejbeer 3280
 
32350 amit.gupta 3281
    @Autowired
3282
    AuthService authService;
3283
 
3284
    public void sendUnscheduledFollowUpMail() throws Exception {
3285
        List<Lead> missedScheduleLeads = leadRepository.selectLeadsScheduledBetweenDate(null, LocalDate.now().atStartOfDay().minusDays(30), LocalDateTime.now().toLocalDate().atStartOfDay());
3286
        List<Lead> leadsScheduledForToday = leadRepository.selectLeadsScheduledBetweenDate(null, LocalDate.now().atStartOfDay(), LocalDate.now().atTime(LocalTime.MAX));
3287
        List<Integer> authIds = missedScheduleLeads.stream().map(x -> x.getAssignTo()).distinct().collect(Collectors.toList());
3288
        LOGGER.info(authIds.size());
35393 amit 3289
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
32350 amit.gupta 3290
        LOGGER.info(authUserMap.size());
3291
        //if(true) return;
3292
 
3293
        missedScheduleLeads = missedScheduleLeads.stream().sorted(Comparator.comparing(Lead::getState, String.CASE_INSENSITIVE_ORDER).thenComparing(Lead::getAssignTo).thenComparing(Lead::getScheduledTimestamp)).collect(Collectors.toList());
3294
        //leadsScheduledForToday
3295
        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
3296
        LOGGER.info("Auth Users Size - {}", authUsers.size());
3297
        for (AuthUser authUser : authUsers) {
3298
            LOGGER.info("Auth Name - {}", authUser.getFullName());
3299
            List<Integer> reporteeAuthIds = authService.getAllReportees(authUser.getId());
3300
            reporteeAuthIds.add(authUser.getId());
3301
            StringBuilder sb = new StringBuilder();
3302
            sb.append("<html><body>");
3303
            List<Lead> authMissedScheduledLeads = missedScheduleLeads.stream().filter(x -> reporteeAuthIds.contains(x.getAssignTo())).collect(Collectors.toList());
3304
            LOGGER.info("authMissedScheduledLeads {}", authMissedScheduledLeads.size());
3305
            if (authMissedScheduledLeads.size() > 0) {
3306
                addMissedScheduledLeadsTable(sb, authMissedScheduledLeads, authUserMap);
3307
                sb.append("</body></html>");
3308
 
3309
                String subject = "Lead Updates Summary";
32421 amit.gupta 3310
                String[] email = Arrays.asList(authUser.getEmailId()).toArray(new String[1]);
3311
                //String[] email = Arrays.asList("amit.gupta@smartdukaan.com").toArray(new String[1]);
36460 ranu 3312
                this.sendMailOfHtmlFormat(googleMailSender, email, sb.toString(), null, subject);
32421 amit.gupta 3313
                //break;
32350 amit.gupta 3314
            }
3315
        }
3316
 
3317
    }
3318
 
32482 amit.gupta 3319
    private void addMissedScheduledLeadsTable(StringBuilder
3320
                                                      sb, List<Lead> missedScheduleLeads, Map<Integer, AuthUser> authUserMap) {
32350 amit.gupta 3321
        sb.append("<h3>Leads That Missed the schedule</h3>");
32439 tejbeer 3322
        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>");
32350 amit.gupta 3323
        for (Lead lead : missedScheduleLeads) {
32439 tejbeer 3324
            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(
3325
                    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>");
32350 amit.gupta 3326
        }
3327
        sb.append("</table>");
3328
    }
3329
 
31697 amit.gupta 3330
    public void notifyVisits() throws Exception {
31886 tejbeer 3331
        List<FranchiseeVisit> franchiseeVisits = franchiseeVisitRepository.selectVisitsScheduledBetweenDate(LocalDateTime.now().minusDays(15), LocalDateTime.now().plusHours(4));
3332
        Map<Integer, String> authUserEmailMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getEmailId()));
3333
        Map<String, Integer> dtrEmailMap = dtrUserRepository.selectAllByEmailIds(new ArrayList<>(authUserEmailMap.values())).stream().collect(Collectors.toMap(x -> x.getEmailId(), x -> x.getId()));
31697 amit.gupta 3334
        Map<Integer, Integer> authUserKeyMap = new HashMap<>();
26790 tejbeer 3335
 
33452 amit.gupta 3336
        for (Entry<Integer, String> authUserEmail : authUserEmailMap.entrySet()) {
31697 amit.gupta 3337
            int authId = authUserEmail.getKey();
3338
            String email = authUserEmail.getValue();
3339
            authUserKeyMap.put(authId, dtrEmailMap.get(email));
3340
        }
3341
        String visitTemplate = "Planned visit to franchisee %s is due by %s";
3342
        String followupTemplate = "Lead followup for franchisee %s is due by %s";
3343
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("MMM 7, EEEE h:m a");
3344
        for (FranchiseeVisit visit : franchiseeVisits) {
3345
            if (authUserKeyMap.containsKey(visit.getAuthId())) {
3346
                continue;
3347
            }
3348
            SendNotificationModel sendNotificationModel = new SendNotificationModel();
3349
            String message = null;
3350
            if (visit.getFranchiseActivityId() == 0) {
31886 tejbeer 3351
                message = String.format(visitTemplate, visit.getPartnerName(), timeFormatter.format(visit.getScheduleTimestamp()));
31697 amit.gupta 3352
                sendNotificationModel.setCampaignName("Franchisee visit Reminder");
3353
            } else {
31886 tejbeer 3354
                message = String.format(followupTemplate, visit.getPartnerName(), timeFormatter.format(visit.getScheduleTimestamp()));
31697 amit.gupta 3355
                sendNotificationModel.setCampaignName("Franchisee followup Reminder");
3356
            }
3357
            sendNotificationModel.setMessage(message);
3358
            sendNotificationModel.setType("url");
3359
            sendNotificationModel.setUrl("https://app.smartdukaan.com/pages/home/notifications");
3360
            sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(2));
3361
            sendNotificationModel.setMessageType(MessageType.reminder);
3362
            sendNotificationModel.setUserIds(Arrays.asList(authUserKeyMap.get(visit.getAuthId())));
3363
            // notificationService.sendNotification(sendNotificationModel);
3364
        }
3365
    }
26792 tejbeer 3366
 
35568 amit 3367
    // REMOVED: Duplicate ticketClosed() - now handled by TicketRelatedScheduledTask.autoCloseResolvedTickets()
3368
    // which uses 8 working days instead of 7 calendar days
26790 tejbeer 3369
 
31697 amit.gupta 3370
    public void checkValidateReferral() throws Exception {
26790 tejbeer 3371
 
31697 amit.gupta 3372
        List<Refferal> referrals = refferalRepository.selectByStatus(RefferalStatus.pending);
3373
        LOGGER.info("referrals" + referrals);
3374
        if (!referrals.isEmpty()) {
3375
            String subject = "Referral Request";
3376
            String messageText = this.getMessageForReferral(referrals);
26790 tejbeer 3377
 
36402 amit 3378
            MimeMessage message = gmailRelaySender.createMimeMessage();
31697 amit.gupta 3379
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
3380
            String[] email = {"kamini.sharma@smartdukaan.com", "tarun.verma@smartdukaan.com"};
3381
            helper.setSubject(subject);
3382
            helper.setText(messageText, true);
3383
            helper.setTo(email);
3384
            InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");
3385
            helper.setFrom(senderAddress);
36402 amit 3386
            gmailRelaySender.send(message);
26790 tejbeer 3387
 
31697 amit.gupta 3388
        }
3389
    }
26790 tejbeer 3390
 
31697 amit.gupta 3391
    private String getMessageForReferral(List<Refferal> referrals) {
3392
        StringBuilder sb = new StringBuilder();
31886 tejbeer 3393
        sb.append("<html><body><p>Alert</p><p>Pending Referrals:-</p>" + "<br/><table style='border:1px solid black ;padding: 5px';>");
3394
        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>");
31697 amit.gupta 3395
        for (Refferal entry : referrals) {
26790 tejbeer 3396
 
31697 amit.gupta 3397
            sb.append("<tr>");
3398
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getRefereeName() + "</td>");
30421 tejbeer 3399
 
31697 amit.gupta 3400
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getRefereeEmail() + "</td>");
3401
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getFirstName() + "</td>");
3402
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getMobile() + "</td>");
3403
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getCity() + "</td>");
3404
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getState() + "</td>");
30421 tejbeer 3405
 
31697 amit.gupta 3406
            sb.append("</tr>");
30421 tejbeer 3407
 
31697 amit.gupta 3408
        }
30421 tejbeer 3409
 
31697 amit.gupta 3410
        sb.append("</tbody></table></body></html>");
30421 tejbeer 3411
 
31697 amit.gupta 3412
        return sb.toString();
3413
    }
30421 tejbeer 3414
 
32832 amit.gupta 3415
    private String getMessageForRBMEscalatedPartners(List<PartnerCollectionRemark> pcrs) throws
32482 amit.gupta 3416
            ProfitMandiBusinessException {
31697 amit.gupta 3417
        StringBuilder sb = new StringBuilder();
32832 amit.gupta 3418
        sb.append("<html><body><p>Alert</p><p>Escalated by RBM-L1:-</p>" + "<br/><table style='border:1px solid black ;padding: 5px';>");
3419
        sb.append("<tbody>" +
3420
                "<tr>" +
3421
                "<th style='border:1px solid black;padding: 5px'>PartnerName</th>" +
3422
                "<th style='border:1px solid black;padding: 5px'>Escalated Since</th>" +
3423
                "<th style='border:1px solid black;padding: 5px'>Message</th>" +
3424
                "</tr>");
30421 tejbeer 3425
 
31697 amit.gupta 3426
        for (PartnerCollectionRemark entry : pcrs) {
30421 tejbeer 3427
 
31697 amit.gupta 3428
            CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());
30421 tejbeer 3429
 
31697 amit.gupta 3430
            sb.append("<tr>");
31886 tejbeer 3431
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")" + "</td>");
3432
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getCreateTimestamp().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");
32832 amit.gupta 3433
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getMessage() + "</td>");
28205 tejbeer 3434
 
31697 amit.gupta 3435
            sb.append("</tr>");
28205 tejbeer 3436
 
31697 amit.gupta 3437
        }
28205 tejbeer 3438
 
31697 amit.gupta 3439
        sb.append("</tbody></table></body></html>");
28205 tejbeer 3440
 
31697 amit.gupta 3441
        return sb.toString();
3442
    }
28208 tejbeer 3443
 
32795 amit.gupta 3444
    private String getMessageForSalesEscalatedPartners(List<PartnerCollectionRemark> pcrs) throws
3445
            ProfitMandiBusinessException {
3446
        StringBuilder sb = new StringBuilder();
3447
        sb.append("<html><body><p>Alert</p><p>Escalated to Sales Team:-</p>" + "<br/>" +
3448
                "<table style='border:1px solid black ;padding: 5px';>");
3449
        sb.append("<tbody>" +
3450
                "<tr>" +
3451
                "<th style='border:1px solid black;padding: 5px'>PartnerName</th>" +
3452
                "<th style='border:1px solid black;padding: 5px'>Escalated Since</th>" +
3453
                "<th style='border:1px solid black;padding: 5px'>Message</th>" +
3454
                "</tr>");
3455
        for (PartnerCollectionRemark entry : pcrs) {
3456
            CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());
3457
            sb.append("<tr>");
3458
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")" + "</td>");
3459
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getCreateTimestamp().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");
3460
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getMessage() + "</td>");
3461
            sb.append("</tr>");
3462
        }
3463
 
3464
        sb.append("</tbody></table></body></html>");
3465
 
3466
        return sb.toString();
3467
    }
3468
 
33078 ranu 3469
    private String getMessageForUnauthorizedBuying(List<NonSdBuying> nsb) throws
3470
            ProfitMandiBusinessException {
3471
        StringBuilder sb = new StringBuilder();
3472
        sb.append("<html><body><p>Alert</p><p>Unauthorized Buying-</p>" + "<br/>" +
3473
                "<table style='border:1px solid black ;padding: 5px';>");
3474
        sb.append("<tbody>" +
3475
                "<tr>" +
3476
                "<th style='border:1px solid black;padding: 5px'>PartnerName</th>" +
3477
                "<th style='border:1px solid black;padding: 5px'>Brand Name</th>" +
3478
                "<th style='border:1px solid black;padding: 5px'>Brand Value</th>" +
3479
                "<th style='border:1px solid black;padding: 5px'>Created At</th>" +
3480
                "<th style='border:1px solid black;padding: 5px'>Reason</th>" +
3481
                "</tr>");
3482
        for (NonSdBuying entry : nsb) {
3483
            CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());
3484
            List<Integer> brandIds = Collections.singletonList(entry.getBrandId());
3485
            BrandCatalog brandsDisplay = brandsRepository.selectByIds(brandIds).get(0);
3486
            sb.append("<tr>");
3487
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")" + "</td>");
3488
            sb.append("<td style='border:1px solid black;padding: 5px'>" + brandsDisplay.getName() + "</td>");
3489
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getBrandValue() + "</td>");
3490
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getCreateTimestamp().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");
3491
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getReason() + "</td>");
3492
            sb.append("</tr>");
3493
        }
3494
 
3495
        sb.append("</tbody></table></body></html>");
3496
 
3497
        return sb.toString();
3498
    }
3499
 
31697 amit.gupta 3500
    public void reverseWallet() throws Exception {
3501
        LocalDate localDate = LocalDate.of(2020, 10, 28);
31886 tejbeer 3502
        List<UserWalletHistory> uwhList = userWalletHistoryRepository.selectAllByDateType(localDate.atStartOfDay(), localDate.plusDays(1).atStartOfDay(), Arrays.asList(WalletReferenceType.SCHEME_IN, WalletReferenceType.SCHEME_OUT));
31697 amit.gupta 3503
        for (UserWalletHistory uwh : uwhList) {
3504
            if (uwh.getBusinessTimestamp().getMonth().equals(Month.SEPTEMBER)) {
3505
                UserWallet uw = userWalletRepository.selectById(uwh.getWalletId());
3506
                // LOGGER.info("UWH - {}", uwh);
3507
                // amount += uwh.getAmount();
3508
                // System.out.println("Amount is - " + amount);
3509
                // walletService.rollbackAmountFromWallet(uw.getUserId(), uwh.getAmount(),
3510
                // uwh.getReference(), uwh.getReferenceType(), "Margin reversal for error prone
3511
                // run", uwh.getBusinessTimestamp());
3512
                int orderId = uwh.getReference();
3513
                FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(orderId);
3514
                int inventoryItemId = 0;
3515
                // fofoOrderRepository.delete(fofoOrder);
3516
                List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
3517
                /*
3518
                 * List<PaymentOptionTransaction> paymentOptionTransactions =
3519
                 * paymentOptionTransactionRepository.selectByReferenceIdAndType(fofoOrder.getId
3520
                 * (), PaymentOptionReferenceType.ORDER); for(PaymentOptionTransaction
3521
                 * paymentOptionTransaction : paymentOptionTransactions) {
3522
                 * //paymentOptionTransactionRepository.delete(paymentOptionTransaction); }
3523
                 */
3524
                for (FofoOrderItem foi : fofoOrderItems) {
3525
                    // fofoOrderItemRepository.delete(foi);
3526
                    List<FofoLineItem> flis = fofoLineItemRepository.selectByFofoOrderItemId(foi.getId());
3527
                    for (FofoLineItem fli : flis) {
3528
                        // fofoLineItemRepository.delete(fli);
3529
                        inventoryItemId = fli.getInventoryItemId();
3530
                    }
3531
                }
3532
                List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectByInventoryItemIds(
33452 amit.gupta 3533
                        Stream.of(inventoryItemId).collect(Collectors.toSet()));
31697 amit.gupta 3534
                for (SchemeInOut sio : schemeInOuts) {
3535
                    if (sio.getCreateTimestamp().toLocalDate().equals(localDate)) {
3536
                        LOGGER.info("SIO - {}", sio);
3537
                        sio.setRolledBackTimestamp(LocalDateTime.now());
3538
                    }
3539
                }
28208 tejbeer 3540
 
31697 amit.gupta 3541
            }
3542
        }
28208 tejbeer 3543
 
31697 amit.gupta 3544
    }
28208 tejbeer 3545
 
31697 amit.gupta 3546
    public void partnerProblemAlert() throws Exception {
3547
        LocalDateTime curDate = LocalDate.now().atStartOfDay();
3548
        Map<Integer, Double> lmtdSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
3549
                curDate.withDayOfMonth(1).minusMonths(1), curDate.with(LocalTime.MAX).minusMonths(1), 0, false);
31886 tejbeer 3550
        Map<Integer, Double> mtdSales = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX), 0, false);
3551
        Map<Integer, PartnerDailyInvestment> pdi = partnerDailyInvestmentRepository.selectAll(LocalDate.now()).stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
28205 tejbeer 3552
 
31697 amit.gupta 3553
        for (Entry<Integer, Double> ls : lmtdSale.entrySet()) {
28208 tejbeer 3554
 
31697 amit.gupta 3555
            double lmtdTwentyPercentSale = ls.getValue() * 0.2;
28208 tejbeer 3556
 
31697 amit.gupta 3557
            LOGGER.info("lmtdTwentyPercentSale" + lmtdTwentyPercentSale);
28208 tejbeer 3558
 
31697 amit.gupta 3559
            double mtdSale = mtdSales.get(ls.getKey()) == null ? 0 : mtdSales.get(ls.getKey());
28205 tejbeer 3560
 
31697 amit.gupta 3561
            LOGGER.info("mtdSale" + mtdSale);
28205 tejbeer 3562
 
31886 tejbeer 3563
            double totalSixtyPercentInvestment = pdi.get(ls.getKey()) == null ? 0 : pdi.get(ls.getKey()).getTotalInvestment() * 0.6;
28205 tejbeer 3564
 
31697 amit.gupta 3565
            LOGGER.info("totalSixtyPercentInvestment" + totalSixtyPercentInvestment);
28205 tejbeer 3566
 
31697 amit.gupta 3567
            double stockInvestment = pdi.get(ls.getKey()) == null ? 0 : pdi.get(ls.getKey()).getInStockAmount();
28205 tejbeer 3568
 
31697 amit.gupta 3569
            LOGGER.info("stockInvestment" + stockInvestment);
28205 tejbeer 3570
 
31697 amit.gupta 3571
            boolean Investmentvalue = partnerInvestmentService.isInvestmentBelow(ls.getKey(), 25);
28205 tejbeer 3572
 
31697 amit.gupta 3573
            PartnerProblem partnerProblem = partnerProblemRepository.selectByFofoId(ls.getKey());
28205 tejbeer 3574
 
31697 amit.gupta 3575
            if (partnerProblem == null) {
3576
                partnerProblem = new PartnerProblem();
3577
                partnerProblem.setFofoId(ls.getKey());
3578
                if (mtdSale < lmtdTwentyPercentSale) {
3579
                    partnerProblem.setMtd(1);
3580
                }
3581
                if (Investmentvalue) {
3582
                    partnerProblem.setInvestment(1);
3583
                }
28205 tejbeer 3584
 
31697 amit.gupta 3585
                if (stockInvestment < totalSixtyPercentInvestment) {
3586
                    partnerProblem.setInvestment(1);
3587
                }
28205 tejbeer 3588
 
31697 amit.gupta 3589
                partnerProblemRepository.persist(partnerProblem);
3590
            } else {
3591
                if (mtdSale < lmtdTwentyPercentSale) {
3592
                    partnerProblem.setMtd(partnerProblem.getMtd() + 1);
28213 tejbeer 3593
 
31697 amit.gupta 3594
                } else {
3595
                    partnerProblem.setMtd(0);
28227 tejbeer 3596
 
31697 amit.gupta 3597
                }
3598
                if (Investmentvalue) {
3599
                    partnerProblem.setInvestment(partnerProblem.getInvestment() + 1);
3600
                } else {
3601
                    partnerProblem.setInvestment(0);
28227 tejbeer 3602
 
31697 amit.gupta 3603
                }
3604
                if (stockInvestment < totalSixtyPercentInvestment) {
3605
                    partnerProblem.setStockInvestment(partnerProblem.getStockInvestment() + 1);
3606
                } else {
3607
                    partnerProblem.setStockInvestment(0);
3608
                }
28213 tejbeer 3609
 
31697 amit.gupta 3610
            }
28213 tejbeer 3611
 
31697 amit.gupta 3612
        }
28213 tejbeer 3613
 
31886 tejbeer 3614
        List<PartnerProblem> partnerProblems = partnerProblemRepository.selectAll().stream().filter(x -> x.getMtd() + x.getInvestment() + x.getStockInvestment() > 0).collect(Collectors.toList());
28205 tejbeer 3615
 
31697 amit.gupta 3616
        partnerProblems = partnerProblems.stream().sorted((x1, x2) -> {
31886 tejbeer 3617
            return x1.getMtd() + x1.getInvestment() + x1.getStockInvestment() < x2.getMtd() + x2.getInvestment() + x2.getStockInvestment() ? 1 : -1;
31697 amit.gupta 3618
        }).collect(Collectors.toList());
28205 tejbeer 3619
 
31697 amit.gupta 3620
        Map<Integer, PartnerProblem> partnerProblemMap = partnerProblems.stream().sorted((x1, x2) -> {
31886 tejbeer 3621
            return x1.getMtd() + x1.getInvestment() + x1.getStockInvestment() < x2.getMtd() + x2.getInvestment() + x2.getStockInvestment() ? 1 : -1;
31697 amit.gupta 3622
        }).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
28205 tejbeer 3623
 
31697 amit.gupta 3624
        Map<Integer, CustomRetailer> customRetailers = retailerService.getAllFofoRetailers();
28205 tejbeer 3625
 
31697 amit.gupta 3626
        List<Integer> assignTo = Arrays.asList(15, 9, 54, 53);
28205 tejbeer 3627
 
35393 amit 3628
        Map<Integer, AuthUser> assignAuthUserMap = authRepository.selectByIds(assignTo).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
28222 tejbeer 3629
 
31886 tejbeer 3630
        List<String> sendTo = Arrays.asList("kamini.sharma@smartdukaan.com", "tarun.verma@smartdukaan.com", "sm@smartdukaan.com");
31697 amit.gupta 3631
        LOGGER.info("partnerProblem" + partnerProblems);
3632
        StringBuilder sb = new StringBuilder();
3633
        sb.append("<htl><body>");
3634
        sb.append(
3635
                "<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>");
31886 tejbeer 3636
        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>"
28218 tejbeer 3637
 
31697 amit.gupta 3638
                + "	    				</tr>");
28218 tejbeer 3639
 
31697 amit.gupta 3640
        for (PartnerProblem pp : partnerProblems) {
3641
            int value = pp.getFofoId() % 4;
28218 tejbeer 3642
 
31697 amit.gupta 3643
            Map<EscalationType, AuthUser> authUserMap = csService.getAuthUserAndEsclationByPartnerId(pp.getFofoId());
3644
            LOGGER.info("authUserMap" + authUserMap);
3645
            sb.append("<tr>");
31886 tejbeer 3646
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailers.get(pp.getFofoId()).getBusinessName() + "</td>");
3647
            sb.append("<td style='border:1px solid black;padding: 5px'>" + assignAuthUserMap.get(assignTo.get(value)).getName() + "</td>");
31697 amit.gupta 3648
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pp.getMtd() + "</td>");
3649
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pp.getInvestment() + "</td>");
3650
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pp.getStockInvestment() + "</td>");
31886 tejbeer 3651
            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>");
28218 tejbeer 3652
 
31697 amit.gupta 3653
            sb.append("</tr>");
3654
        }
3655
        sb.append("</tbody></table><br><br>");
3656
        String subject = "Partner Problem Alert!";
3657
        String[] email = sendTo.toArray(new String[sendTo.size()]);
28227 tejbeer 3658
 
36460 ranu 3659
        this.sendMailOfHtmlFormat(googleMailSender, email, sb.toString(), null, subject);
28227 tejbeer 3660
 
31697 amit.gupta 3661
        Map<Integer, List<Integer>> authUserPartnerMapping = csService.getAuthUserIdPartnerIdMapping();
28224 tejbeer 3662
 
31697 amit.gupta 3663
        for (Entry<Integer, List<Integer>> authUserPartner : authUserPartnerMapping.entrySet()) {
3664
            AuthUser authUser = authRepository.selectById(authUserPartner.getKey());
3665
            for (Integer patnerId : authUserPartner.getValue()) {
3666
                if (partnerProblemMap.get(patnerId) != null) {
28230 tejbeer 3667
 
31697 amit.gupta 3668
                    StringBuilder sbbuilder = new StringBuilder();
3669
                    sbbuilder.append("<hml><body>");
3670
                    sb.append(
3671
                            "<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>");
31886 tejbeer 3672
                    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>"
28218 tejbeer 3673
 
31697 amit.gupta 3674
                            + "	    				</tr>");
28205 tejbeer 3675
 
31697 amit.gupta 3676
                    for (Integer partnerId : authUserPartner.getValue()) {
3677
                        if (partnerProblemMap.get(partnerId) != null) {
3678
                            PartnerProblem pp = partnerProblemMap.get(partnerId);
3679
                            sbbuilder.append("<tr>");
31886 tejbeer 3680
                            sbbuilder.append("<td style='border:1px solid black;padding: 5px'>" + customRetailers.get(pp.getFofoId()).getBusinessName() + "</td>");
3681
                            sbbuilder.append("<td style='border:1px solid black;padding: 5px'>" + pp.getMtd() + "</td>");
31697 amit.gupta 3682
                            sbbuilder.append(
3683
                                    "<td style='border:1px solid black;padding: 5px'>" + pp.getInvestment() + "</td>");
31886 tejbeer 3684
                            sbbuilder.append("<td style='border:1px solid black;padding: 5px'>" + pp.getStockInvestment() + "</td>");
28790 amit.gupta 3685
 
31697 amit.gupta 3686
                            sbbuilder.append("</tr>");
3687
                        }
28790 amit.gupta 3688
 
31697 amit.gupta 3689
                    }
3690
                    sbbuilder.append("</tbody></table><br><br>");
29488 manish 3691
 
36460 ranu 3692
                    this.sendMailOfHtmlFormat(googleMailSender, new String[]{authUser.getEmailId()}, sbbuilder.toString(), null, subject);
31697 amit.gupta 3693
                }
29488 manish 3694
 
31697 amit.gupta 3695
            }
3696
        }
3697
    }
28775 amit.gupta 3698
 
31697 amit.gupta 3699
    @Autowired
3700
    WarehouseRepository warehouseRepository;
29488 manish 3701
 
33256 amit.gupta 3702
    public void getVendorWarehouses(int warehouseId) throws ProfitMandiBusinessException {
31697 amit.gupta 3703
        LOGGER.info("Warehouses - {}", warehouseRepository.getVendorWarehouses().get(warehouseId));
29488 manish 3704
 
31697 amit.gupta 3705
    }
29488 manish 3706
 
31697 amit.gupta 3707
    public void checkImeiActivation() {
29801 manish 3708
 
31697 amit.gupta 3709
        try {
3710
            vivoImeiActivationService.checkImeiActivation();
3711
        } catch (ProfitMandiBusinessException e) {
3712
            e.printStackTrace();
3713
        } catch (IOException e) {
3714
            e.printStackTrace();
3715
        } catch (Exception e) {
3716
            e.printStackTrace();
3717
        }
29807 manish 3718
 
31697 amit.gupta 3719
    }
29801 manish 3720
 
36253 amit 3721
    public void checkImeiActivationTertiary() {
3722
 
3723
        try {
3724
            vivoImeiActivationService.checkImeiActivationTertiary();
3725
        } catch (ProfitMandiBusinessException e) {
3726
            e.printStackTrace();
3727
        } catch (IOException e) {
3728
            e.printStackTrace();
3729
        } catch (Exception e) {
3730
            e.printStackTrace();
3731
        }
3732
 
3733
    }
3734
 
31697 amit.gupta 3735
    public void checkItelImeiActivation(LocalDate date, Integer day) {
3736
        LOGGER.info("Hello - {}", "hhh");
29488 manish 3737
 
31697 amit.gupta 3738
        try {
3739
            itelImeiActivationService.checkItelImeiActivation(date, day);
3740
        } catch (ProfitMandiBusinessException e) {
3741
            // TODO Auto-generated catch block
3742
            e.printStackTrace();
3743
        } catch (IOException e) {
3744
            // TODO Auto-generated catch block
3745
            e.printStackTrace();
3746
        } catch (Exception e) {
3747
            // TODO Auto-generated catch block
3748
            e.printStackTrace();
3749
        }
29488 manish 3750
 
31697 amit.gupta 3751
    }
29488 manish 3752
 
32482 amit.gupta 3753
    public void selectFinServiceFollowUpDateByCurrDate(LocalDate currentDate) throws
3754
            MessagingException, ProfitMandiBusinessException, IOException {
31697 amit.gupta 3755
        LOGGER.info("selectfinServiceFollow - {}", "selectfinServiceFollowUpDateByCurrDate");
29308 tejbeer 3756
 
31697 amit.gupta 3757
        serviceConfigService.selectFinServicePartnerfollowUpDateByCurrentDate(currentDate);
29252 amit.gupta 3758
 
31697 amit.gupta 3759
    }
29451 manish 3760
 
31697 amit.gupta 3761
    public void checkTecnoImeiActivation(LocalDate date, Integer day) {
3762
        LOGGER.info("Hello - {}", "hhh");
29308 tejbeer 3763
 
31697 amit.gupta 3764
        try {
3765
            tecnoImeiActivation.checkTecnoImeiActivation(date, day);
3766
        } catch (ProfitMandiBusinessException e) {
3767
            // TODO Auto-generated catch block
3768
            e.printStackTrace();
3769
        } catch (IOException e) {
3770
            // TODO Auto-generated catch block
3771
            e.printStackTrace();
3772
        } catch (Exception e) {
3773
            // TODO Auto-generated catch block
3774
            e.printStackTrace();
3775
        }
29308 tejbeer 3776
 
31697 amit.gupta 3777
    }
29441 tejbeer 3778
 
31697 amit.gupta 3779
    public void checkCancellationMargin() throws Exception {
3780
        LocalDateTime startDate = LocalDate.of(2021, 4, 1).atStartOfDay();
3781
        List<FofoOrder> fofoOrders = fofoOrderRepository.selectCancelledBetweenSaleDate(startDate, LocalDateTime.now());
3782
        LOGGER.info("Total Orders =  {}", fofoOrders.size());
3783
        for (FofoOrder fofoOrder : fofoOrders) {
31886 tejbeer 3784
            List<UserWalletHistory> history = userWalletHistoryRepository.selectAllByreferenceIdandreferenceType(fofoOrder.getId(), WalletReferenceType.SCHEME_OUT);
3785
            history.addAll(userWalletHistoryRepository.selectAllByreferenceIdandreferenceType(fofoOrder.getId(), WalletReferenceType.ACTIVATION_SCHEME));
31697 amit.gupta 3786
            int walletSum = history.stream().mapToInt(x -> x.getAmount()).sum();
3787
            if (Math.abs(walletSum) > 1) {
3788
                // LOGGER.info("Cancelled invoice {}, Order Id = {}, = havent rolledback, Value
3789
                // = {}", fofoOrder.getInvoiceNumber(), fofoOrder.getId(), walletSum);
3790
                List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
3791
                List<FofoLineItem> flis = fofoLineItemRepository.selectByFofoOrderItemId(fofoOrderItems.get(0).getId());
3792
                FofoLineItem fli = flis.get(0);
3793
                if (StringUtils.isEmpty(fli.getSerialNumber()))
3794
                    continue;
31886 tejbeer 3795
                List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectByInventoryItemIds(new HashSet<>(Arrays.asList(fli.getInventoryItemId())));
31697 amit.gupta 3796
                InventoryItem inventoryItem = inventoryItemRepository.selectById(fli.getInventoryItemId());
31886 tejbeer 3797
                double schemeSum = schemeInOuts.stream().filter(x -> x.getRolledBackTimestamp() == null).mapToDouble(x -> x.getAmount()).sum();
31697 amit.gupta 3798
                /*
3799
                 * if(inventoryItem.getGoodQuantity()==1) {
3800
                 * LOGGER.info("GoodQty, Serial Number {}, InventoryItem = {}, Billed on {}",
3801
                 * inventoryItem.getSerialNumber(), inventoryItem.getId(),
3802
                 * inventoryItem.getUpdateTimestamp()); } else
3803
                 * if(inventoryItem.getBadQuantity()==1){
3804
                 * LOGGER.info("Bad Qty, Serial Number {}, InventoryItem = {}, Billed on {}",
3805
                 * inventoryItem.getSerialNumber(), inventoryItem.getId(),
3806
                 * inventoryItem.getUpdateTimestamp()); } else if
3807
                 * (inventoryItem.getLastScanType().equals(ScanType.SALE)) { LOGGER.
3808
                 * info("Problem Sold, Serial Number {}, InventoryItem = {}, Billed on {}",
3809
                 * inventoryItem.getSerialNumber(), inventoryItem.getId(),
3810
                 * inventoryItem.getUpdateTimestamp()); }
3811
                 */
31886 tejbeer 3812
                if (inventoryItem.getLastScanType().equals(ScanType.SALE) || inventoryItem.getLastScanType().equals(ScanType.SALE_RET)) {
3813
                    Map<String, Double> map = schemeInOuts.stream().collect(
3814
                            groupingBy(
3815
                                    x -> DateTimeFormatter.ofPattern("yyyyMMddHH").format(x.getCreateTimestamp()) + "- " + x.getSchemeId(), Collectors.summingDouble(x -> x.getAmount())));
33452 amit.gupta 3816
                    for (Entry<String, Double> entry : map.entrySet()) {
31697 amit.gupta 3817
                        LOGGER.info("{} = {}", entry.getKey(), entry.getValue());
3818
                    }
31886 tejbeer 3819
                    LOGGER.info("id- {}, imei- {}, lastScan = {}, Scheme sum - {}", inventoryItem.getId(), inventoryItem.getSerialNumber(), inventoryItem.getLastScanType(), schemeSum);
31697 amit.gupta 3820
                }
3821
            }
3822
        }
29441 tejbeer 3823
 
31697 amit.gupta 3824
    }
29308 tejbeer 3825
 
31697 amit.gupta 3826
    public static String readFileAsString(String file) throws Exception {
3827
        String data = "";
3828
        data = new String(Files.readAllBytes(Paths.get(file)));
3829
        return data;
3830
    }
29308 tejbeer 3831
 
31697 amit.gupta 3832
    @Autowired
3833
    private PartnerCollectionRemarkRepository partnerCollectionRemarkRepository;
30421 tejbeer 3834
 
32832 amit.gupta 3835
    //RBM L2 Escalations
32482 amit.gupta 3836
    public void reviewUncontactablePartner() throws
3837
            ProfitMandiBusinessException, MessagingException, UnsupportedEncodingException {
30421 tejbeer 3838
 
31697 amit.gupta 3839
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(true);
30421 tejbeer 3840
 
32832 amit.gupta 3841
        List<Integer> partnerLastCollectionRemarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(new ArrayList<>(customRetailerMap.keySet()));
30859 tejbeer 3842
 
32832 amit.gupta 3843
        if (!partnerLastCollectionRemarkIds.isEmpty()) {
3844
            List<PartnerCollectionRemark> partnerCollectionRemarks = partnerCollectionRemarkRepository.selectByIds(partnerLastCollectionRemarkIds);
30421 tejbeer 3845
 
33064 ranu 3846
            Map<Integer, PartnerCollectionRemark> rbmEscalatedRemarksMap = partnerCollectionRemarks.stream().filter(x -> x.getRemark().equals(CollectionRemark.RBM_L2_ESCALATION)).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
36269 ranu 3847
            Map<Integer, PartnerCollectionRemark> rbmL3EscalatedRemarksMap = partnerCollectionRemarks.stream().filter(x -> x.getRemark().equals(CollectionRemark.RBM_L3_ESCALATION)).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
32832 amit.gupta 3848
            Map<Integer, PartnerCollectionRemark> salesEscalatedRemarksMap = partnerCollectionRemarks.stream().filter(x -> x.getRemark().equals(CollectionRemark.SALES_ESCALATION)).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
30859 tejbeer 3849
 
32832 amit.gupta 3850
 
3851
            if (!rbmEscalatedRemarksMap.isEmpty()) {
3852
                //
33452 amit.gupta 3853
                for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_RBM), true).entrySet()) {
32832 amit.gupta 3854
                    List<PartnerCollectionRemark> filteredRows = storeGuyEntry.getValue().stream()
3855
                            .map(x -> rbmEscalatedRemarksMap.get(x)).filter(x -> x != null).collect(Collectors.toList());
3856
                    String subject = "Partners escalated to RBM-L2";
3857
                    String messageText = this.getMessageForRBMEscalatedPartners(filteredRows);
3858
 
36402 amit 3859
                    MimeMessage message = gmailRelaySender.createMimeMessage();
31697 amit.gupta 3860
                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
3861
                    String[] email = new String[]{storeGuyEntry.getKey()};
30859 tejbeer 3862
 
31697 amit.gupta 3863
                    helper.setSubject(subject);
3864
                    helper.setText(messageText, true);
3865
                    helper.setTo(email);
31886 tejbeer 3866
                    InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");
31697 amit.gupta 3867
                    helper.setFrom(senderAddress);
36402 amit 3868
                    gmailRelaySender.send(message);
30859 tejbeer 3869
 
36269 ranu 3870
                }
3871
            }
3872
            if (!rbmL3EscalatedRemarksMap.isEmpty()) {
3873
                //
3874
                for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_RBM), true).entrySet()) {
3875
                    List<PartnerCollectionRemark> filteredRows = storeGuyEntry.getValue().stream()
3876
                            .map(x -> rbmL3EscalatedRemarksMap.get(x)).filter(x -> x != null).collect(Collectors.toList());
3877
                    String subject = "Partners escalated to RBM-L3";
3878
                    String messageText = this.getMessageForRBMEscalatedPartners(filteredRows);
30859 tejbeer 3879
 
36402 amit 3880
                    MimeMessage message = gmailRelaySender.createMimeMessage();
36269 ranu 3881
                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
3882
                    String[] email = new String[]{storeGuyEntry.getKey()};
3883
 
3884
                    helper.setSubject(subject);
3885
                    helper.setText(messageText, true);
3886
                    helper.setTo(email);
3887
                    InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");
3888
                    helper.setFrom(senderAddress);
36402 amit 3889
                    gmailRelaySender.send(message);
36269 ranu 3890
 
31697 amit.gupta 3891
                }
3892
            }
32832 amit.gupta 3893
            if (!salesEscalatedRemarksMap.isEmpty()) {
3894
                //
35521 amit 3895
                for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_ABM, ProfitMandiConstants.TICKET_CATEGORY_RBM), true).entrySet()) {
32832 amit.gupta 3896
                    List<PartnerCollectionRemark> filteredRows = storeGuyEntry.getValue().stream()
3897
                            .map(x -> salesEscalatedRemarksMap.get(x)).filter(x -> x != null).collect(Collectors.toList());
3898
                    String subject = "Partners escalated to Sales";
3899
                    String messageText = this.getMessageForSalesEscalatedPartners(filteredRows);
30936 tejbeer 3900
 
36402 amit 3901
                    MimeMessage message = gmailRelaySender.createMimeMessage();
32832 amit.gupta 3902
                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
3903
                    String[] email = new String[]{storeGuyEntry.getKey()};
3904
 
3905
                    helper.setSubject(subject);
3906
                    helper.setText(messageText, true);
3907
                    helper.setTo(email);
3908
                    InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");
3909
                    helper.setFrom(senderAddress);
36402 amit 3910
                    gmailRelaySender.send(message);
32832 amit.gupta 3911
 
3912
                }
3913
            }
3914
 
31697 amit.gupta 3915
        }
3916
    }
30936 tejbeer 3917
 
33078 ranu 3918
 
31697 amit.gupta 3919
    @Autowired
33078 ranu 3920
    private NonSdBuyingRepository nonSdBuyingRepository;
3921
 
3922
    //Non Sd Buying
3923
    public void reviewNonSdBuyingBrand() throws
3924
            ProfitMandiBusinessException, MessagingException, UnsupportedEncodingException {
3925
        List<NonSdBuying> nonSdByuingActiveList = nonSdBuyingRepository.selectAllActiveNonSDBuyingList(true);
3926
        Map<Integer, NonSdBuying> unAuthorizedBuyingMap = nonSdByuingActiveList.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
3927
 
3928
        if (!unAuthorizedBuyingMap.isEmpty()) {
35521 amit 3929
            for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_ABM), true).entrySet()) {
33078 ranu 3930
                List<NonSdBuying> unAuthorizedfilteredRows = storeGuyEntry.getValue().stream()
3931
                        .map(x -> unAuthorizedBuyingMap.get(x)).filter(x -> x != null).collect(Collectors.toList());
33112 amit.gupta 3932
                if (!unAuthorizedfilteredRows.isEmpty()) {
33078 ranu 3933
                    String subject = "Unauthorized Buying";
3934
                    String messageText = this.getMessageForUnauthorizedBuying(unAuthorizedfilteredRows);
3935
 
36402 amit 3936
                    MimeMessage message = gmailRelaySender.createMimeMessage();
33078 ranu 3937
                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
3938
                    String[] email = new String[]{storeGuyEntry.getKey()};
3939
 
3940
                    helper.setSubject(subject);
3941
                    helper.setText(messageText, true);
3942
                    helper.setTo(email);
3943
                    InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");
3944
                    helper.setFrom(senderAddress);
36402 amit 3945
                    gmailRelaySender.send(message);
33078 ranu 3946
                    LOGGER.info("unAuthorizedfilteredRows {}", unAuthorizedfilteredRows);
3947
                }
3948
 
3949
 
3950
            }
3951
 
3952
        }
3953
    }
3954
 
3955
    @Autowired
31697 amit.gupta 3956
    private LoanRepository loanRepository;
31020 tejbeer 3957
 
31697 amit.gupta 3958
    @Autowired
3959
    private LoanStatementRepository loanStatementRepository;
30859 tejbeer 3960
 
31697 amit.gupta 3961
    @Autowired
3962
    private SDCreditRequirementRepository sdCreditRequirementRepository;
30859 tejbeer 3963
 
31697 amit.gupta 3964
    @Autowired
3965
    private CurrentPartnerDailyInvestmentRepository currentPartnerDailyInvestmentRepository;
30859 tejbeer 3966
 
31697 amit.gupta 3967
    @Autowired
3968
    private TransactionRepository transactionRepository;
30859 tejbeer 3969
 
31697 amit.gupta 3970
    @Autowired
3971
    private SanctionRequestRepository sanctionRequestRepository;
30859 tejbeer 3972
 
31697 amit.gupta 3973
    public void calculateInterestAccured() throws ProfitMandiBusinessException {
36289 amit 3974
        synchronized (SD_CREDIT_LOCK) {
3975
            List<Loan> loans = loanRepository.selectAllActiveLoan();
30859 tejbeer 3976
 
36289 amit 3977
            for (Loan loan : loans) {
3978
                List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(loan.getId());
3979
                Map<LoanReferenceType, Double> loanStatusAmount = loanStatements.stream().collect(groupingBy(
3980
                        x -> x.getLoanReferenceType(), Collectors.summingDouble(x -> x.getAmount().doubleValue())));
30936 tejbeer 3981
 
36289 amit 3982
                // Interest starts from this date (inclusive). Under current policy (MIN_FREE_DAYS=1),
3983
                // this is at minimum createdOn + 1 — billing day is always free.
3984
                LocalDate interestStartDate = com.spice.profitmandi.service.transaction.SDCreditServiceImpl.computeInterestStartDate(loan);
30936 tejbeer 3985
 
36289 amit 3986
                LOGGER.info("Loan id - {}, interestStartDate {}", loan.getId(), interestStartDate);
3987
                if (!LocalDate.now().isBefore(interestStartDate)) {
3988
                    int loanStatementId = loanStatementRepository.selectLatestLoanSatement(loan.getFofoId(), loan.getId());
3989
                    LOGGER.info("loanStatementId {}", loanStatementId);
3990
                    if (loanStatementId != 0) {
3991
                        this.calculateInterest(loan, loanStatusAmount, loanStatementId);
3992
                    } else {
3993
                        sdCreditService.addInterest(interestStartDate, LocalDate.now(), loan, loanStatusAmount);
3994
                    }
31697 amit.gupta 3995
                }
32724 amit.gupta 3996
            }
31697 amit.gupta 3997
        }
3998
    }
30936 tejbeer 3999
 
31697 amit.gupta 4000
    @Autowired
4001
    FofoPaymentRepository fofoPaymentRepository;
30936 tejbeer 4002
 
31697 amit.gupta 4003
    @Autowired
4004
    CCAvenuePaymentService ccAvenuePaymentService;
30936 tejbeer 4005
 
31697 amit.gupta 4006
    public void settleCCAvePayments() throws Exception {
31886 tejbeer 4007
        List<FofoPayment> fofoPayments = fofoPaymentRepository.selectAllByGatewayStatus(Gateway.CCAVENUE, PaymentStatus.INIT).stream().filter(x -> x.getCreateTimestamp().isBefore(LocalDateTime.now().minusMinutes(30l))).collect(Collectors.toList());
31697 amit.gupta 4008
        for (FofoPayment fofoPayment : fofoPayments) {
4009
            ccAvenuePaymentService.updatePayment(fofoPayment);
4010
        }
4011
    }
30859 tejbeer 4012
 
31697 amit.gupta 4013
    /*
4014
     * public void getCCAvenuePendingOrderStatus(int pendingOrderId) { PendingOrder
4015
     * pendingOrder = pendingOrderRepository.selectById(pendingOrderId);
4016
     * ccAvenuePaymentService.getPaymentStatusMap(pendingOrder); }
4017
     */
30859 tejbeer 4018
 
32482 amit.gupta 4019
    private void calculateInterest(Loan loan, Map<LoanReferenceType, Double> loanStatusAmount,
4020
                                   int loanStatementId) throws ProfitMandiBusinessException {
31697 amit.gupta 4021
        LoanStatement loanStatement = loanStatementRepository.selectById(loanStatementId);
30859 tejbeer 4022
 
31697 amit.gupta 4023
        if (loanStatement.getLoanId() == loan.getId()) {
34710 amit.gupta 4024
            sdCreditService.addInterest(loanStatement.getCreatedAt().toLocalDate().plusDays(1), LocalDate.now(), loan, loanStatusAmount);
31697 amit.gupta 4025
        } else {
4026
            throw new ProfitMandiBusinessException("loanstament", loanStatement.getLoanId(), "Invalid LoanId");
4027
        }
4028
    }
31175 tejbeer 4029
 
31697 amit.gupta 4030
    public void loanSettlement() throws Exception {
36289 amit 4031
        synchronized (SD_CREDIT_LOCK) {
4032
            List<Loan> loans = loanRepository.selectAllActiveLoanForSettlement().stream().filter(x -> x.canBeSettled()).collect(toList());
4033
            //TODO:Upto here
4034
            if (!loans.isEmpty()) {
31020 tejbeer 4035
 
36289 amit 4036
                for (Loan loan : loans) {
4037
                    LOGGER.info("Loan - {},  {}", loan.getId(), loan.canBeSettled());
4038
                    double settledAmount = sdCreditService.settleLoan(loan);
30859 tejbeer 4039
 
36289 amit 4040
                    List<SanctionRequest> sanctionRequests = sanctionRequestRepository.selectHoldSanctionByFofoId(loan.getFofoId());
4041
                    for (SanctionRequest sanctionRequest : sanctionRequests) {
31175 tejbeer 4042
 
36289 amit 4043
                        List<Order> orders = orderRepository.selectAllByTransactionId(sanctionRequest.getTransactionId());
4044
                        if (orders.size() == 0) {
4045
                            LOGGER.info("Could not find orders - for Sanction Request {}", sanctionRequest);
4046
                            continue;
4047
                        }
30999 tejbeer 4048
 
36289 amit 4049
                        if (settledAmount >= sanctionRequest.getPendingAmount().doubleValue()) {
4050
                            settledAmount -= sanctionRequest.getPendingAmount().doubleValue();
4051
                            sanctionRequest.setPendingAmount(BigDecimal.valueOf(0));
4052
                            this.sendUnholdEmail(orders);
4053
                        } else {
4054
                            double pendinAmount = sanctionRequest.getPendingAmount().doubleValue() - settledAmount;
4055
                            System.out.println("Pending Amount - " + pendinAmount);
4056
                            sanctionRequest.setPendingAmount(BigDecimal.valueOf(pendinAmount));
4057
                            break;
33828 ranu 4058
 
36289 amit 4059
                        }
4060
 
34275 tejus.loha 4061
                    }
36289 amit 4062
                }
34162 ranu 4063
 
32439 tejbeer 4064
            }
34275 tejus.loha 4065
        }
33664 amit.gupta 4066
 
32439 tejbeer 4067
    }
31020 tejbeer 4068
 
4069
 
32439 tejbeer 4070
    private void sendUnholdEmail(List<Order> orders) throws Exception {
30859 tejbeer 4071
 
4072
 
32439 tejbeer 4073
        orders.forEach(x -> x.setShipmentHold(false));
33452 amit.gupta 4074
        orders = orders.stream().filter(x -> x.getRefundTimestamp() != null).collect(Collectors.toList());
33506 amit.gupta 4075
        if (orders.size() > 0) {
33427 amit.gupta 4076
 
33664 amit.gupta 4077
            double totalAmount = orders.stream().collect(Collectors.summingDouble(x -> x.getTotalAmount()));
30859 tejbeer 4078
 
33506 amit.gupta 4079
            List<String> authUserEmail = csService.getAuthUserIdByPartnerId(orders.get(0).getRetailerId()).stream().map(x -> x.getEmailId()).collect(Collectors.toList());
4080
            authUserEmail.add("vinay.p@smartdukaan.com");
4081
            authUserEmail.add("shivam.gupta@smartdukaan.com");
30859 tejbeer 4082
 
33506 amit.gupta 4083
            String[] emailTo = authUserEmail.toArray(new String[authUserEmail.size()]);
30859 tejbeer 4084
 
33506 amit.gupta 4085
            String[] ccTo = {"tarun.verma@smartdukaan.com", "kamini.sharma@smartdukaan.com"};
30859 tejbeer 4086
 
33664 amit.gupta 4087
            String subject = "Dispatch held orders of - " + (orders.get(0).getRetailerName());
4088
            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.");
35959 amit 4089
            mailOutboxService.queueMailViaGoogle(emailTo, ccTo, subject, message, "ScheduledTasks.sendUnholdEmail");
33506 amit.gupta 4090
        }
30859 tejbeer 4091
 
32439 tejbeer 4092
 
31697 amit.gupta 4093
    }
30859 tejbeer 4094
 
36745 ranu 4095
    // Nightly at 23:30: detect beat-days the assignee missed (no PUNCHIN, or punched
4096
    // in but no stops worked) and fan out per-stop miss rows into beat_deferred_visit
4097
    // so the Deferred Partners panel surfaces them. Idempotent on repeat runs.
4098
    @Scheduled(cron = "0 30 23 * * *")
4099
    public void detectMissedBeats() {
4100
        try {
4101
            beatMissDetectorRunner.syncMissesForDate(java.time.LocalDate.now());
4102
        } catch (Exception e) {
4103
            LOGGER.error("detectMissedBeats failed", e);
4104
        }
4105
    }
4106
 
37172 amit 4107
    // Nightly PJP agenda sync: evaluate the 5 AUTO agenda rules per partner and
4108
    // open/close user.agenda_instance rows. Scheduled from ScheduledSkeleton at
4109
    // 23:45 — after the 23:30 activation-type cron, so the REVIVAL mirror sees
4110
    // today's state.
4111
    public void updatePjpAgendaInstances() {
4112
        AgendaSyncResult result = agendaAutoRuleService.syncAllPartners();
4113
        LOGGER.info("updatePjpAgendaInstances: {}", result);
4114
        if (result.getErrors() > 0) {
4115
            String body = "PJP agenda sync finished with errors.\n\n" + result + "\n\n"
4116
                    + String.join("\n", result.getErrorDetails());
4117
            mailOutboxService.queueMailViaGoogle(
4118
                    "amit.gupta@smartdukaan.com",
37173 amit 4119
                    new String[]{},
37172 amit 4120
                    "PJP agenda sync: " + result.getErrors() + " errors",
4121
                    body,
4122
                    "ScheduledTasks.updatePjpAgendaInstances");
4123
        }
4124
    }
4125
 
36561 amit 4126
    @Scheduled(cron = "0 0 1 * * *")
36556 amit 4127
    public void convertExpiredFlagshipCredits() {
4128
        synchronized (SD_CREDIT_LOCK) {
4129
            try {
4130
                sdCreditService.convertExpiredFlagshipCredits();
4131
            } catch (Exception e) {
4132
                LOGGER.error("Error converting expired flagship credits", e);
4133
            }
4134
        }
4135
    }
4136
 
36561 amit 4137
    public void testFlagshipBilling(int transactionId, double invoiceAmount, String invoiceNumber) {
4138
        synchronized (SD_CREDIT_LOCK) {
4139
            try {
4140
                System.out.println("=== TEST: Calling createLoanForBilling ===");
4141
                System.out.println("transactionId=" + transactionId + ", invoiceAmount=" + invoiceAmount + ", invoiceNumber=" + invoiceNumber);
4142
                sdCreditService.createLoanForBilling(transactionId, invoiceAmount, invoiceNumber);
4143
                System.out.println("=== TEST: createLoanForBilling completed ===");
4144
            } catch (Exception e) {
4145
                System.out.println("=== TEST: ERROR ===");
4146
                e.printStackTrace();
4147
            }
4148
        }
4149
    }
4150
 
36556 amit 4151
    public void notifyFlagshipExpiryIn2Days() {
4152
        try {
4153
            java.time.LocalDate expiryDate = java.time.LocalDate.now().plusDays(2);
4154
            List<Loan> expiringLoans = loanRepository.selectFlagshipLoansExpiringOn(expiryDate);
4155
            LOGGER.info("Found {} flagship credits expiring on {}", expiringLoans.size(), expiryDate);
4156
 
4157
            Map<Integer, List<Loan>> byPartner = expiringLoans.stream()
4158
                    .collect(java.util.stream.Collectors.groupingBy(Loan::getFofoId));
4159
 
4160
            for (Map.Entry<Integer, List<Loan>> entry : byPartner.entrySet()) {
4161
                int fofoId = entry.getKey();
4162
                List<Loan> loans = entry.getValue();
4163
                double totalAmount = loans.stream().mapToDouble(l -> l.getPendingAmount().doubleValue()).sum();
4164
 
4165
                String title = "Flagship Credit Expiring Soon";
4166
                String message = String.format(
4167
                        "Your flagship credit of Rs.%.0f will convert to a regular loan on %s. " +
4168
                        "Sell the items before then to avoid interest charges.",
4169
                        totalAmount, expiryDate.format(java.time.format.DateTimeFormatter.ofPattern("dd-MMM-yyyy")));
4170
 
4171
                try {
4172
                    int userId = userAccountRepository.selectUserIdByRetailerId(fofoId);
4173
                    SendNotificationModel model = new SendNotificationModel();
4174
                    model.setCampaignName("Flagship credit expiry reminder");
4175
                    model.setTitle(title);
4176
                    model.setMessage(message);
4177
                    model.setType("url");
4178
                    model.setUrl("https://app.smartdukaan.com/pages/home/credit");
4179
                    model.setExpiresat(java.time.LocalDateTime.now().plusDays(2));
4180
                    model.setMessageType(MessageType.reminder);
4181
                    model.setUserIds(java.util.Arrays.asList(userId));
4182
                    notificationService.sendNotification(model);
4183
                } catch (Exception e) {
4184
                    LOGGER.error("Failed to send flagship expiry notification to fofoId {}", fofoId, e);
4185
                }
4186
            }
4187
        } catch (Exception e) {
4188
            LOGGER.error("Error sending flagship expiry notifications", e);
4189
        }
4190
    }
4191
 
32307 amit.gupta 4192
    public void dailyLoanAlert() throws Exception {
31697 amit.gupta 4193
        List<Loan> loans = loanRepository.selectAllActiveLoan();
30859 tejbeer 4194
 
31697 amit.gupta 4195
        Map<Integer, Double> partnerLoanAmount = new HashMap<>();
30859 tejbeer 4196
 
35877 amit 4197
        for (Loan loan : loans) {
4198
            double amount = partnerLoanAmount.getOrDefault(loan.getFofoId(), 0.0);
4199
            amount += loan.getPendingAmount().doubleValue() + loan.getInterestAccrued().doubleValue() - loan.getInterestPaid().doubleValue();
4200
            partnerLoanAmount.put(loan.getFofoId(), amount);
31697 amit.gupta 4201
        }
30859 tejbeer 4202
 
31697 amit.gupta 4203
        if (!partnerLoanAmount.isEmpty()) {
30965 tejbeer 4204
 
31697 amit.gupta 4205
            for (Entry<Integer, Double> partnerLoanAmountEnrty : partnerLoanAmount.entrySet()) {
30859 tejbeer 4206
 
31697 amit.gupta 4207
                int fofoId = partnerLoanAmountEnrty.getKey();
30859 tejbeer 4208
 
31697 amit.gupta 4209
                com.spice.profitmandi.dao.entity.user.User user = userUserRepository.selectById(fofoId);
30859 tejbeer 4210
 
31697 amit.gupta 4211
                Address address = addressRepository.selectById(user.getAddressId());
30896 amit.gupta 4212
 
31697 amit.gupta 4213
                String title = "Alert Credit Outstanding!";
4214
                String url = "http://app.smartdukaan.com/pages/home/credit";
34729 amit.gupta 4215
                String message = "Your total outstanding Credit Balance is Rs." + FormattingUtils.formatDecimal(Math.abs(partnerLoanAmountEnrty.getValue())) + ".";
31697 amit.gupta 4216
                notificationService.sendNotification(fofoId, title, MessageType.notification, title, message, url);
30913 tejbeer 4217
 
32841 amit.gupta 4218
                //notificationService.sendWhatsappMessage(message, title, address.getPhoneNumber());
30913 tejbeer 4219
 
31697 amit.gupta 4220
            }
30917 tejbeer 4221
 
31697 amit.gupta 4222
        }
30917 tejbeer 4223
 
31697 amit.gupta 4224
    }
30920 tejbeer 4225
 
31697 amit.gupta 4226
    public void processActivatedImeisForSchemes() throws ProfitMandiBusinessException {
4227
        schemeService.processActivatedImeisForSchemes();
4228
    }
30920 tejbeer 4229
 
33112 amit.gupta 4230
    @Autowired
33355 amit.gupta 4231
    SidbiService sidbiService;
33112 amit.gupta 4232
 
33364 amit.gupta 4233
    public void processSidbiDeductions() throws ProfitMandiBusinessException {
33434 amit.gupta 4234
        //sidbiService.migrateSanctions();
33355 amit.gupta 4235
        sidbiService.processDeductions();
4236
    }
35521 amit 4237
 
35326 amit 4238
    public void updatePartnerLimit(int fofoId) throws ProfitMandiBusinessException {
4239
        LocalDateTime firstBillingDate = transactionRepository.getFirstBillingDate(fofoId);
33355 amit.gupta 4240
 
35326 amit 4241
        CreditAccount creditAccount = creditAccountRepository.selectByFofoIdAndGateway(fofoId, Gateway.SDDIRECT);
35393 amit 4242
        BigDecimal utilizationAmount = sdCreditService.getUtilizationAmount(fofoId);
35326 amit 4243
        PartnerDailyInvestment partnerDailyInvestment = partnerInvestmentService.getInvestment(fofoId, 0);
4244
        BigDecimal suggestedAmount = this.getSuggestedAmount(creditAccount, partnerDailyInvestment, utilizationAmount, null);
4245
        SDCreditRequirement sdCreditRequirement = sdCreditRequirementRepository.selectByFofoId(fofoId);
4246
 
4247
        LOGGER.info("suggestedAmount {} ", suggestedAmount);
4248
 
4249
        if (sdCreditRequirement == null) {
4250
            sdCreditRequirement = new SDCreditRequirement();
4251
            sdCreditRequirement.setFofoId(fofoId);
4252
            sdCreditRequirement.setCreditDays(15);
4253
            sdCreditRequirement.setInterestRate(ProfitMandiConstants.NEW_INTEREST_RATE);
4254
            sdCreditRequirement.setRisk(CreditRisk.HIGH_RISK);
4255
            sdCreditRequirement.setUtilizedAmount(BigDecimal.ZERO);
4256
            sdCreditRequirement.setCreateTimestamp(LocalDateTime.now());
4257
            sdCreditRequirement.setUpdateTimestamp(LocalDateTime.now());
4258
            sdCreditRequirementRepository.persist(sdCreditRequirement);
4259
        }
4260
 
4261
        CreditRisk creditRisk = sdCreditService.getCurrentRisk(sdCreditRequirement, firstBillingDate);
4262
 
4263
        sdCreditRequirement.setRisk(creditRisk);
4264
        LOGGER.info("Suggested Amount - {}", suggestedAmount);
4265
        sdCreditRequirement.setSuggestedLimit(suggestedAmount);
4266
        if (!sdCreditRequirement.isHardLimit()) {
4267
            sdCreditRequirement.setLimit(suggestedAmount);
4268
        }
35811 amit 4269
        BigDecimal availableLimit = sdCreditRequirement.getLimit().subtract(utilizationAmount);
35326 amit 4270
 
35811 amit 4271
        LOGGER.info("utilizedLimit {} ", utilizationAmount);
35326 amit 4272
 
4273
        LOGGER.info("availableLimit {} ", availableLimit);
4274
 
35811 amit 4275
        sdCreditRequirement.setUtilizedAmount(utilizationAmount);
35326 amit 4276
 
4277
        sdCreditRequirement.setUpdateTimestamp(LocalDateTime.now());
4278
 
4279
        if (creditAccount != null) {
4280
 
4281
            creditAccount.setInterestRate(sdCreditRequirement.getInterestRate().floatValue());
4282
            creditAccount.setSanctionedAmount(sdCreditRequirement.getLimit().floatValue());
4283
            creditAccount.setAvailableAmount(availableLimit.floatValue());
4284
            creditAccount.setFreeDays(sdCreditRequirement.getFreeDays());
4285
            creditAccount.setUpdatedOn(LocalDateTime.now());
4286
        }
4287
 
4288
    }
35521 amit 4289
 
31697 amit.gupta 4290
    public void updatePartnerLimit() throws ProfitMandiBusinessException {
36289 amit 4291
        synchronized (SD_CREDIT_LOCK) {
4292
            Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(true);
4293
            Map<Integer, BigDecimal> fofoSidbiLimitMap = sidbiService.getSuggestedLimitMap();
4294
            Map<Integer, SDCreditRequirement> sdCreditRequirementMap = sdCreditRequirementRepository.selectAll().stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
4295
            Map<Integer, CreditAccount> creditAccountMap = creditAccountRepository.selectAllByGateways(Arrays.asList(Gateway.SIDBI, Gateway.SDDIRECT))
4296
                    .stream().filter(x -> x.isActive()).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
4297
            Map<Integer, BulkCreditSummary> bulkSummaryMap = sdCreditService.getCreditSummaryBulk();
33287 amit.gupta 4298
 
36289 amit 4299
            // Sort by fofoId to ensure deterministic row-locking order and prevent deadlocks
4300
            List<Integer> sortedFofoIds = customRetailerMap.keySet().stream().sorted().collect(Collectors.toList());
30929 tejbeer 4301
 
36289 amit 4302
            for (int fofoId : sortedFofoIds) {
4303
                CustomRetailer customRetailer = customRetailerMap.get(fofoId);
4304
                LocalDateTime firstBillingDate = transactionRepository.getFirstBillingDate(fofoId);
30913 tejbeer 4305
 
36289 amit 4306
                CreditAccount creditAccount = creditAccountMap.get(fofoId);
4307
                BulkCreditSummary bulkSummary = bulkSummaryMap.get(fofoId);
4308
                BigDecimal utilizationAmount = bulkSummary != null ? bulkSummary.getUtilization() : BigDecimal.ZERO;
4309
                PartnerDailyInvestment partnerDailyInvestment = partnerInvestmentService.getInvestment(fofoId, 0);
4310
                BigDecimal suggestedAmount = this.getSuggestedAmount(creditAccount, partnerDailyInvestment, utilizationAmount, fofoSidbiLimitMap.get(fofoId));
4311
                SDCreditRequirement sdCreditRequirement = sdCreditRequirementMap.get(fofoId);
30913 tejbeer 4312
 
36289 amit 4313
                LOGGER.info("suggestedAmount {} ", suggestedAmount);
30913 tejbeer 4314
 
36289 amit 4315
                if (sdCreditRequirement == null) {
4316
                    sdCreditRequirement = new SDCreditRequirement();
4317
                    sdCreditRequirement.setFofoId(fofoId);
4318
                    sdCreditRequirement.setCreditDays(15);
4319
                    sdCreditRequirement.setInterestRate(ProfitMandiConstants.NEW_INTEREST_RATE);
4320
                    sdCreditRequirement.setRisk(CreditRisk.HIGH_RISK);
4321
                    sdCreditRequirement.setUtilizedAmount(BigDecimal.ZERO);
4322
                    sdCreditRequirement.setCreateTimestamp(LocalDateTime.now());
4323
                    sdCreditRequirement.setUpdateTimestamp(LocalDateTime.now());
4324
                    sdCreditRequirementRepository.persist(sdCreditRequirement);
4325
                }
30913 tejbeer 4326
 
36289 amit 4327
                CreditRisk creditRisk = sdCreditService.getCurrentRisk(sdCreditRequirement, firstBillingDate);
30934 tejbeer 4328
 
36289 amit 4329
                sdCreditRequirement.setRisk(creditRisk);
30934 tejbeer 4330
 
36289 amit 4331
                sdCreditRequirement.setSuggestedLimit(suggestedAmount);
4332
                if (!sdCreditRequirement.isHardLimit()) {
4333
                    sdCreditRequirement.setLimit(suggestedAmount);
4334
                }
30913 tejbeer 4335
 
36289 amit 4336
                BigDecimal availableLimit = sdCreditRequirement.getLimit().subtract(utilizationAmount);
30913 tejbeer 4337
 
36289 amit 4338
                LOGGER.info("utilizedLimit {} ", utilizationAmount);
30929 tejbeer 4339
 
36289 amit 4340
                LOGGER.info("availableLimit {} ", availableLimit);
30929 tejbeer 4341
 
36289 amit 4342
                sdCreditRequirement.setUtilizedAmount(utilizationAmount);
30929 tejbeer 4343
 
36289 amit 4344
                sdCreditRequirement.setUpdateTimestamp(LocalDateTime.now());
4345
 
4346
                if (creditAccount != null) {
4347
 
4348
                    creditAccount.setInterestRate(sdCreditRequirement.getInterestRate().floatValue());
4349
                    creditAccount.setSanctionedAmount(sdCreditRequirement.getLimit().floatValue());
4350
                    creditAccount.setAvailableAmount(availableLimit.floatValue());
4351
                    creditAccount.setFreeDays(sdCreditRequirement.getFreeDays());
4352
                    creditAccount.setUpdatedOn(LocalDateTime.now());
4353
                }
4354
 
31697 amit.gupta 4355
            }
4356
        }
31177 tejbeer 4357
 
31697 amit.gupta 4358
    }
34502 amit.gupta 4359
 
34374 amit.gupta 4360
    private static final NavigableMap<Double, Double> discountMap = new TreeMap<>();
34502 amit.gupta 4361
 
34374 amit.gupta 4362
    static {
34852 amit 4363
        discountMap.put(4 * ProfitMandiConstants.ONE_LAC - 1, 0.2);    // Up to 3,99,999 -> 20%
4364
        discountMap.put(10 * ProfitMandiConstants.ONE_LAC - 1, 0.25);  // 4,00,000 to 9,99,999 -> 25%
4365
        discountMap.put(20 * ProfitMandiConstants.ONE_LAC - 1, 0.3);   // 10,00,000 to 19,99,999 -> 30%
4366
        discountMap.put(Double.MAX_VALUE, 0.4);                        // 20,00,000 and above -> 40%
34374 amit.gupta 4367
    }
34502 amit.gupta 4368
 
4369
    public BigDecimal getSuggestedLimit(double investmentValue) {
34374 amit.gupta 4370
        double percentageValue = discountMap.ceilingEntry(investmentValue).getValue();
34510 amit.gupta 4371
        return this.getSuggestedAmount(investmentValue, percentageValue);
4372
 
4373
    }
4374
 
4375
    private BigDecimal getSuggestedAmount(double investmentValue, double percentageValue) {
34374 amit.gupta 4376
        return BigDecimal.valueOf(investmentValue * percentageValue);
4377
    }
34502 amit.gupta 4378
 
35299 amit 4379
    /*private static List<Integer> hundredPercentLimitPartnerIds = Arrays.asList(175139630,
34510 amit.gupta 4380
            175139815,
4381
            175139844,
4382
            175140101
35299 amit 4383
    );*/
34510 amit.gupta 4384
 
35299 amit 4385
    private static List<Integer> hundredPercentLimitPartnerIds = Arrays.asList();
4386
 
35177 amit 4387
    private BigDecimal getSuggestedAmount(CreditAccount creditAccount, PartnerDailyInvestment
35393 amit 4388
            partnerDailyInvestment, BigDecimal utilizationAmount, BigDecimal sidbiLimit) {
33112 amit.gupta 4389
        BigDecimal suggestedAmount = BigDecimal.ZERO;
35393 amit 4390
        double utilization = utilizationAmount != null ? utilizationAmount.doubleValue() : 0;
33112 amit.gupta 4391
        //1 LAC
33295 amit.gupta 4392
        if (creditAccount == null || creditAccount.getGateway().equals(Gateway.SDDIRECT)) {
33112 amit.gupta 4393
 
35177 amit 4394
            if (partnerDailyInvestment != null) {
4395
                if (hundredPercentLimitPartnerIds.contains(partnerDailyInvestment.getFofoId())) {
35393 amit 4396
                    suggestedAmount = getSuggestedAmount(partnerDailyInvestment.getTotalInvestment() - utilization, 1);
34512 amit.gupta 4397
                    suggestedAmount = suggestedAmount.min(BigDecimal.valueOf(1500000));
34510 amit.gupta 4398
                } else {
35393 amit 4399
                    suggestedAmount = getSuggestedLimit(partnerDailyInvestment.getTotalInvestment() - utilization);
34510 amit.gupta 4400
                }
33112 amit.gupta 4401
            }
4402
            if (suggestedAmount.doubleValue() < 0) {
4403
                suggestedAmount = BigDecimal.ZERO;
4404
            }
33355 amit.gupta 4405
        } else if (creditAccount.getGateway().equals(Gateway.SIDBI) && sidbiLimit != null) {
35393 amit 4406
            suggestedAmount = getSuggestedLimit(partnerDailyInvestment.getTotalInvestment() - utilization);
34993 ranu 4407
            suggestedAmount = suggestedAmount.max(sidbiLimit);
4408
 
4409
 
33112 amit.gupta 4410
        }
4411
        return suggestedAmount;
4412
    }
4413
 
31697 amit.gupta 4414
    public void notifyDefaultLoans() throws ProfitMandiBusinessException, MessagingException, IOException {
36462 ranu 4415
        synchronized (SD_CREDIT_LOCK) {
36289 amit 4416
            sdCreditService.updateRisk();
4417
            List<Loan> defaultLoans = sdCreditService.getDefaultLoans();
4418
            if (!defaultLoans.isEmpty()) {
4419
                this.sendDefaultLoanAlert(defaultLoans);
4420
            }
36462 ranu 4421
        }
31697 amit.gupta 4422
    }
30929 tejbeer 4423
 
32482 amit.gupta 4424
    public void sendDefaultLoanAlert(List<Loan> defaultLoans) throws
4425
            ProfitMandiBusinessException, MessagingException, IOException {
31697 amit.gupta 4426
        String subject = "Default Partners";
30931 tejbeer 4427
 
35591 aman 4428
        List<Integer> categoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_CATEGORY, ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_ABM, ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT);
30929 tejbeer 4429
 
33452 amit.gupta 4430
        for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false).entrySet()) {
31697 amit.gupta 4431
            List<Loan> filteredRows = new ArrayList<>();
4432
            for (Loan loan : defaultLoans) {
30929 tejbeer 4433
 
31697 amit.gupta 4434
                if (storeGuyEntry.getValue().contains(loan.getFofoId())) {
30929 tejbeer 4435
 
31697 amit.gupta 4436
                    filteredRows.add(loan);
4437
                }
4438
            }
4439
            if (!filteredRows.isEmpty()) {
35591 aman 4440
                String[] email = new String[]{storeGuyEntry.getKey(),"neeraj.gupta@smartdukaan.com"};
31697 amit.gupta 4441
                String messageText = this.getMessageForDueDateExtend(filteredRows);
36473 amit 4442
                this.sendMailOfHtmlFormat(googleMailSender, email, messageText, null, subject);
30982 tejbeer 4443
 
31697 amit.gupta 4444
            }
30936 tejbeer 4445
 
31697 amit.gupta 4446
        }
33628 tejus.loha 4447
        String messageText = this.getMessageForDueDateExtend(defaultLoans);
36473 amit 4448
        this.sendMailOfHtmlFormat(googleMailSender, new String[]{"puneet.wahi@smartdukaan.com", "rahul.latwal@smartdukaan.com", "dilbag.singh@smartdukaan.com"}, messageText, null, subject);
30982 tejbeer 4449
 
31697 amit.gupta 4450
        for (Loan defaultLoan : defaultLoans) {
35877 amit 4451
            double principal = defaultLoan.getPendingAmount().doubleValue();
4452
            double interest = defaultLoan.getInterestAccrued().doubleValue() - defaultLoan.getInterestPaid().doubleValue();
4453
            double total = principal + interest;
30929 tejbeer 4454
 
35877 amit 4455
            String title = "Credit Default Alert!";
31697 amit.gupta 4456
            String url = "http://app.smartdukaan.com/pages/home/credit";
35915 amit 4457
            String message = "Your credit payment (due " + defaultLoan.getDueDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")) + ") is now in default. A penalty interest of " + (defaultLoan.getPenaltyRate() != null ? defaultLoan.getPenaltyRate() : ProfitMandiConstants.NEW_DELAYED_INTEREST_RATE) + "% per day is being charged. Total outstanding: Rs." + FormattingUtils.formatDecimal(total) + " (Principal: Rs." + FormattingUtils.formatDecimal(principal) + " + Interest: Rs." + FormattingUtils.formatDecimal(interest) + "). Pay immediately to avoid further penalties.";
31886 tejbeer 4458
            notificationService.sendNotification(defaultLoan.getFofoId(), title, MessageType.notification, title, message, url);
30936 tejbeer 4459
 
31697 amit.gupta 4460
        }
4461
    }
30929 tejbeer 4462
 
31697 amit.gupta 4463
    private String getMessageForDueDateExtend(List<Loan> loans) throws ProfitMandiBusinessException {
33553 ranu 4464
        Map<Integer, com.spice.profitmandi.dao.model.FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();
4465
        Map<Integer, FofoRBMReportingModel> fofoRbmReportingModelMap = csService.getPartnerIdRBMHeaders();
4466
        List<AST> asts = astRepository.selectAll();
4467
        Map<Integer, AST> astMap = asts.stream()
4468
                .collect(Collectors.toMap(AST::getId, ast -> ast));
31697 amit.gupta 4469
        StringBuilder sb = new StringBuilder();
4470
        sb.append(
35877 amit 4471
                "<html><body><p>Alert</p><p>Default Partners :-</p>" + "<br/><p>Penalty interest of " + ProfitMandiConstants.NEW_DELAYED_INTEREST_RATE + "% per day is being charged on outstanding amount.</p>" + "<br/>" +
33553 ranu 4472
                        "<table style='border:1px solid black ;padding: 5px';>");
4473
        sb.append("<tbody>\n" +
4474
                "<tr>\n" +
4475
                "<th style='border:1px solid black;padding: 5px'>PartnerName</th>\n" +
33555 ranu 4476
                "<th style='border:1px solid black;padding: 5px'>State Name</th>\n" +
4477
                "<th style='border:1px solid black;padding: 5px'>Area</th>\n" +
4478
                "<th style='border:1px solid black;padding: 5px'>Territory</th>\n" +
33553 ranu 4479
                "<th style='border:1px solid black;padding: 5px'>due date</th>\n" +
4480
                "<th style='border:1px solid black;padding: 5px'>Days</th>\n" +
33664 amit.gupta 4481
                "<th style='border:1px solid black;padding: 5px'>Pending Amount</th>\n" +
33810 ranu 4482
                "<th style='border:1px solid black;padding: 5px'>RBM L2</th>\n" +
33553 ranu 4483
                "<th style='border:1px solid black;padding: 5px'>RBM L1</th>\n" +
4484
                "<th style='border:1px solid black;padding: 5px'>Sales L1</th>\n" +
4485
                "<th style='border:1px solid black;padding: 5px'>Sales L2</th>\n" +
4486
                "</tr>");
35877 amit 4487
        DecimalFormat df = new DecimalFormat("#.##");
31697 amit.gupta 4488
        for (Loan entry : loans) {
30929 tejbeer 4489
 
35877 amit 4490
            double amount = entry.getPendingAmount().doubleValue() + entry.getInterestAccrued().doubleValue() - entry.getInterestPaid().doubleValue();
30929 tejbeer 4491
 
31697 amit.gupta 4492
            long noOfdaysBetween = ChronoUnit.DAYS.between(entry.getDueDate().toLocalDate(), LocalDateTime.now());
30929 tejbeer 4493
 
31697 amit.gupta 4494
            CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());
30929 tejbeer 4495
 
31697 amit.gupta 4496
            sb.append("<tr>");
31886 tejbeer 4497
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")" + "</td>");
33555 ranu 4498
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getAddress().getState() + "</td>");
4499
            sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getArea() + "</td>");
4500
            sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getTerritory() + "</td>");
31886 tejbeer 4501
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getDueDate().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");
31697 amit.gupta 4502
            sb.append("<td style='border:1px solid black;padding: 5px'>" + noOfdaysBetween + "</td>");
35877 amit 4503
            sb.append("<td style='border:1px solid black;padding: 5px'>" + df.format(amount) + "</td>");
33553 ranu 4504
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL1Manager() + "</td>");
4505
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL2Manager() + "</td>");
4506
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getTerritoryManager() + "</td>");
4507
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getRegionalManager() + "</td>");
31397 tejbeer 4508
 
31697 amit.gupta 4509
            sb.append("</tr>");
31397 tejbeer 4510
 
31697 amit.gupta 4511
        }
31397 tejbeer 4512
 
31697 amit.gupta 4513
        sb.append("</tbody></table></body></html>");
31397 tejbeer 4514
 
31697 amit.gupta 4515
        return sb.toString();
4516
    }
31397 tejbeer 4517
 
35111 ranu 4518
    private String getMessageForDueDateCross(List<Loan> dueDateCrossLoans) throws ProfitMandiBusinessException {
33161 ranu 4519
        Map<Integer, com.spice.profitmandi.dao.model.FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();
33452 amit.gupta 4520
        Map<Integer, FofoRBMReportingModel> fofoRbmReportingModelMap = csService.getPartnerIdRBMHeaders();
33553 ranu 4521
        List<AST> asts = astRepository.selectAll();
4522
        Map<Integer, AST> astMap = asts.stream()
4523
                .collect(Collectors.toMap(AST::getId, ast -> ast));
4524
 
31697 amit.gupta 4525
        StringBuilder sb = new StringBuilder();
35877 amit 4526
        sb.append("<html><body><p>Alert</p><p>Partner Credit Report - Overdue :-</p>" + "<br/><p>Overdue interest of " + ProfitMandiConstants.TIER2_INTEREST_RATE + "% per day is being charged on outstanding amount.</p>" + "<br/>" +
33161 ranu 4527
                "<table style='border:1px solid black ;padding: 5px';>");
4528
        sb.append("<tbody>\n" + "<tr>\n" +
33256 amit.gupta 4529
                "<th style='border:1px solid black;padding: 5px'>PartnerName</th>\n" +
36303 aman 4530
                "<th style='border:1px solid black;padding: 5px'>Code</th>\n" +
33256 amit.gupta 4531
                "<th style='border:1px solid black;padding: 5px'>State Name</th>\n" +
33555 ranu 4532
                "<th style='border:1px solid black;padding: 5px'>Area</th>\n" +
33553 ranu 4533
                "<th style='border:1px solid black;padding: 5px'>Territory</th>\n" +
33256 amit.gupta 4534
                "<th style='border:1px solid black;padding: 5px'>due date</th>\n" +
4535
                "<th style='border:1px solid black;padding: 5px'>Days</th>\n" +
4536
                "<th style='border:1px solid black;padding: 5px'>Pending Amount</th>\n" +
33810 ranu 4537
                "<th style='border:1px solid black;padding: 5px'>RBM L2</th>\n" +
33256 amit.gupta 4538
                "<th style='border:1px solid black;padding: 5px'>RBM L1</th>\n" +
4539
                "<th style='border:1px solid black;padding: 5px'>Sales L1</th>\n" +
4540
                "<th style='border:1px solid black;padding: 5px'>Sales L2</th>\n" +
35107 ranu 4541
                "<th style='border:1px solid black;padding: 5px'>Limit Assigned</th>\n" +
33161 ranu 4542
                "</tr>");
31397 tejbeer 4543
 
35877 amit 4544
        DecimalFormat df = new DecimalFormat("#.##");
35111 ranu 4545
        for (Loan entry : dueDateCrossLoans) {
31397 tejbeer 4546
 
35877 amit 4547
            double amount = entry.getPendingAmount().doubleValue() + entry.getInterestAccrued().doubleValue() - entry.getInterestPaid().doubleValue();
31397 tejbeer 4548
 
31697 amit.gupta 4549
            long noOfdaysBetween = ChronoUnit.DAYS.between(entry.getDueDate().toLocalDate(), LocalDateTime.now());
31397 tejbeer 4550
 
31697 amit.gupta 4551
            CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());
31397 tejbeer 4552
 
35106 ranu 4553
            SDCreditRequirement sdCreditRequirement = sdCreditRequirementRepository.selectByFofoId(customRetailer.getPartnerId());
4554
 
31697 amit.gupta 4555
            sb.append("<tr>");
36303 aman 4556
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "</td>");
4557
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getCode() + "</td>");
33162 ranu 4558
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getAddress().getState() + "</td>");
33553 ranu 4559
            sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getArea() + "</td>");
4560
            sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getTerritory() + "</td>");
31886 tejbeer 4561
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getDueDate().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");
31697 amit.gupta 4562
            sb.append("<td style='border:1px solid black;padding: 5px'>" + noOfdaysBetween + "</td>");
35877 amit 4563
            sb.append("<td style='border:1px solid black;padding: 5px'>" + df.format(amount) + "</td>");
33161 ranu 4564
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL1Manager() + "</td>");
4565
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL2Manager() + "</td>");
4566
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getTerritoryManager() + "</td>");
4567
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getRegionalManager() + "</td>");
35521 amit 4568
            sb.append("<td style='border:1px solid black;padding: 5px'>" + df.format(sdCreditRequirement.getLimit()) + "</td>");
31697 amit.gupta 4569
            sb.append("</tr>");
4570
        }
31397 tejbeer 4571
 
31697 amit.gupta 4572
        sb.append("</tbody></table></body></html>");
31397 tejbeer 4573
 
31697 amit.gupta 4574
        return sb.toString();
4575
    }
31397 tejbeer 4576
 
32307 amit.gupta 4577
    public void notifyLoanDueDateCross() throws Exception {
31397 tejbeer 4578
 
35111 ranu 4579
        List<Loan> dueDateCrossLoans = sdCreditService.getDueDateCrossLoan();
4580
        List<Loan> allActiveLoans = sdCreditService.getAllActiveLoan();
31697 amit.gupta 4581
        if (!dueDateCrossLoans.isEmpty()) {
35521 amit 4582
            this.sendDueDateCrossLoanAlert(dueDateCrossLoans, allActiveLoans);
31697 amit.gupta 4583
        }
31397 tejbeer 4584
 
31697 amit.gupta 4585
    }
31397 tejbeer 4586
 
35521 amit 4587
    private void sendDueDateCrossLoanAlert(List<Loan> dueDateCrossLoans, List<Loan> allActiveLoans) throws Exception {
35591 aman 4588
        List<Integer> categoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_CATEGORY, ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_ABM, ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT);
31397 tejbeer 4589
 
35115 ranu 4590
        for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false).entrySet()) {
33631 tejus.loha 4591
            List<Loan> filteredRows = new ArrayList<>();
31697 amit.gupta 4592
            for (Loan loan : dueDateCrossLoans) {
30936 tejbeer 4593
 
31697 amit.gupta 4594
                if (storeGuyEntry.getValue().contains(loan.getFofoId())) {
30982 tejbeer 4595
 
31697 amit.gupta 4596
                    filteredRows.add(loan);
4597
                }
4598
            }
35111 ranu 4599
 
35112 ranu 4600
            List<Loan> filteredAllActiveLoans = new ArrayList<>();
35111 ranu 4601
            for (Loan loan : allActiveLoans) {
4602
 
4603
                if (storeGuyEntry.getValue().contains(loan.getFofoId())) {
4604
 
35112 ranu 4605
                    filteredAllActiveLoans.add(loan);
35111 ranu 4606
                }
4607
            }
4608
 
35112 ranu 4609
            ByteArrayOutputStream byteArrayOutputStream = null;
4610
            Utils.Attachment attachment1 = null;
35521 amit 4611
            if (!filteredAllActiveLoans.isEmpty()) {
4612
                byteArrayOutputStream = this.generateLoanCsv(filteredAllActiveLoans);
4613
                attachment1 = new Utils.Attachment("partnner-credit.csv", new ByteArrayResource(byteArrayOutputStream.toByteArray()));
35111 ranu 4614
 
4615
            }
4616
 
4617
 
31697 amit.gupta 4618
            if (!filteredRows.isEmpty()) {
4619
                String messageText = this.getMessageForDueDateCross(filteredRows);
35591 aman 4620
                String[] email = new String[]{storeGuyEntry.getKey(),"neeraj.gupta@smartdukaan.com"};
30982 tejbeer 4621
 
35521 amit 4622
                if (attachment1 != null) {
35959 amit 4623
                    mailOutboxService.queueMailWithAttachmentsViaGoogle(email, null, null, "Partner Credit Report", messageText, true, "ScheduledTasks.sendDueDateCrossLoanAlert", attachment1);
35521 amit 4624
                } else {
36460 ranu 4625
                    this.sendMailOfHtmlFormat(googleMailSender, email, messageText, null, "Due Date Cross");
30936 tejbeer 4626
 
35521 amit 4627
                }
4628
 
31697 amit.gupta 4629
            }
30936 tejbeer 4630
 
35115 ranu 4631
        }
35113 ranu 4632
 
4633
        String messageText = this.getMessageForDueDateCross(dueDateCrossLoans);
4634
        ByteArrayOutputStream byteArrayOutputStream = this.generateLoanCsv(allActiveLoans);
4635
        Utils.Attachment attachment = null;
35521 amit 4636
        if (byteArrayOutputStream != null) {
4637
            attachment = new Utils.Attachment("partnner-credit.csv", new ByteArrayResource(byteArrayOutputStream.toByteArray()));
35113 ranu 4638
 
31697 amit.gupta 4639
        }
33628 tejus.loha 4640
 
35521 amit 4641
        if (attachment != null) {
35959 amit 4642
            mailOutboxService.queueMailWithAttachmentsViaGoogle(new String[]{"sdtech@smartdukaan.com"}, null, null, "Partner Credit Report", messageText, true, "ScheduledTasks.sendDueDateCrossLoanAlert", attachment);
35521 amit 4643
        } else {
36460 ranu 4644
            this.sendMailOfHtmlFormat(googleMailSender, new String[]{"sdtech@smartdukaan.com"}, messageText, null, "Due Date Cross");
35113 ranu 4645
        }
33628 tejus.loha 4646
 
35111 ranu 4647
 
31697 amit.gupta 4648
        if (!dueDateCrossLoans.isEmpty()) {
4649
            for (Loan loan : dueDateCrossLoans) {
35877 amit 4650
                double principal = loan.getPendingAmount().doubleValue();
4651
                double interest = loan.getInterestAccrued().doubleValue() - loan.getInterestPaid().doubleValue();
4652
                double total = principal + interest;
30936 tejbeer 4653
 
31697 amit.gupta 4654
                String url = "http://app.smartdukaan.com/pages/home/credit";
30936 tejbeer 4655
 
35877 amit 4656
                String title = "Credit Payment Overdue!";
35915 amit 4657
                String message = "Your credit payment (due " + loan.getDueDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")) + ") is overdue. An interest of " + (loan.getOverdueRate() != null ? loan.getOverdueRate() : ProfitMandiConstants.TIER2_INTEREST_RATE) + "% per day is now being charged. Total outstanding: Rs." + FormattingUtils.formatDecimal(total) + " (Principal: Rs." + FormattingUtils.formatDecimal(principal) + " + Interest: Rs." + FormattingUtils.formatDecimal(interest) + "). Pay now to avoid higher penalties.";
30936 tejbeer 4658
 
31886 tejbeer 4659
                notificationService.sendNotification(loan.getFofoId(), title, MessageType.notification, title, message, url);
30936 tejbeer 4660
 
31697 amit.gupta 4661
            }
4662
        }
30982 tejbeer 4663
 
31697 amit.gupta 4664
    }
30936 tejbeer 4665
 
35112 ranu 4666
    private ByteArrayOutputStream generateLoanCsv(List<Loan> loans) throws ProfitMandiBusinessException {
4667
        org.apache.commons.io.output.ByteArrayOutputStream byteArrayOutputStream = null;
4668
 
4669
 
4670
        if (!loans.isEmpty()) {
4671
            Map<Integer, com.spice.profitmandi.dao.model.FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();
4672
            Map<Integer, FofoRBMReportingModel> fofoRbmReportingModelMap = csService.getPartnerIdRBMHeaders();
4673
            List<AST> asts = astRepository.selectAll();
4674
            Map<Integer, AST> astMap = asts.stream()
4675
                    .collect(Collectors.toMap(AST::getId, ast -> ast));
4676
            try {
4677
                List<String> headers = Arrays.asList(
4678
                        "PartnerName", "State Name", "Area", "Territory",
4679
                        "Due Date", "Days", "Pending Amount",
4680
                        "RBM L2", "RBM L1", "Sales L1", "Sales L2", "Limit Assigned"
4681
                );
4682
 
4683
                List<List<?>> rows = new ArrayList<>();
4684
 
35877 amit 4685
                DecimalFormat df = new DecimalFormat("#.##");
35112 ranu 4686
                for (Loan entry : loans) {
4687
 
35877 amit 4688
                    double amount = entry.getPendingAmount().doubleValue() + entry.getInterestAccrued().doubleValue() - entry.getInterestPaid().doubleValue();
35112 ranu 4689
 
35114 ranu 4690
                    long noOfdaysBetween = ChronoUnit.DAYS.between(entry.getCreatedOn().toLocalDate(), LocalDateTime.now());
35112 ranu 4691
 
4692
                    CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());
4693
                    SDCreditRequirement sdCreditRequirement = sdCreditRequirementRepository.selectByFofoId(customRetailer.getPartnerId());
4694
                    List<String> row = Arrays.asList(
4695
                            customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")",
4696
                            customRetailer.getAddress().getState(),
4697
                            astMap.get(customRetailer.getAstId()).getArea(),
4698
                            astMap.get(customRetailer.getAstId()).getTerritory(),
4699
                            entry.getDueDate().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")),
4700
                            String.valueOf(noOfdaysBetween),
35877 amit 4701
                            df.format(amount),
35112 ranu 4702
                            fofoRbmReportingModelMap.get(entry.getFofoId()).getL1Manager(),
4703
                            fofoRbmReportingModelMap.get(entry.getFofoId()).getL2Manager(),
4704
                            fofoReportingModelMap.get(entry.getFofoId()).getTerritoryManager(),
4705
                            fofoReportingModelMap.get(entry.getFofoId()).getRegionalManager(),
4706
                            df.format(sdCreditRequirement.getLimit())
4707
                    );
4708
 
4709
                    rows.add(row);
4710
                }
4711
 
4712
                byteArrayOutputStream = FileUtil.getCSVByteStream(headers, rows);
4713
 
4714
 
4715
            } catch (Exception e) {
4716
                throw new RuntimeException(e);
4717
            }
4718
 
4719
        }
4720
        return byteArrayOutputStream;
4721
    }
4722
 
4723
 
32307 amit.gupta 4724
    public void alertForDueDate() throws Exception {
30936 tejbeer 4725
 
31697 amit.gupta 4726
        List<Loan> loans = loanRepository.selectAllActiveLoan();
30936 tejbeer 4727
 
35877 amit 4728
        for (Loan loan : loans) {
4729
            long noOfdaysBetween = ChronoUnit.DAYS.between(LocalDate.now(), loan.getDueDate().toLocalDate());
30936 tejbeer 4730
 
35877 amit 4731
            LOGGER.info("noOfdaysBetween {} ", noOfdaysBetween);
30936 tejbeer 4732
 
35877 amit 4733
            if (noOfdaysBetween <= 4 && noOfdaysBetween >= 0) {
4734
                double amount = loan.getPendingAmount().doubleValue() + loan.getInterestAccrued().doubleValue() - loan.getInterestPaid().doubleValue();
30936 tejbeer 4735
 
35877 amit 4736
                String title = "Alert!";
4737
                String url = "http://app.smartdukaan.com/pages/home/credit";
4738
                String message;
4739
                if (noOfdaysBetween == 0) {
4740
                    message = "Your total outstanding Credit amount is Rs." + FormattingUtils.formatDecimal(amount) + " is due for Today, Pay Now!!";
4741
                } else {
4742
                    message = "Your total outstanding Credit amount is Rs." + FormattingUtils.formatDecimal(amount) + " is due by " + loan.getDueDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")) + " , Pay Now!!";
31697 amit.gupta 4743
                }
35877 amit 4744
                notificationService.sendNotification(loan.getFofoId(), title, MessageType.notification, title, message, url);
31697 amit.gupta 4745
            }
4746
        }
30984 tejbeer 4747
 
31697 amit.gupta 4748
    }
30982 tejbeer 4749
 
32307 amit.gupta 4750
    public void userMobileNumberOptIn() throws Exception {
30982 tejbeer 4751
 
31697 amit.gupta 4752
        List<FofoStore> fofoStores = fofoStoreRepository.selectActiveStores();
30982 tejbeer 4753
 
31886 tejbeer 4754
        List<com.spice.profitmandi.dao.entity.user.User> users = userUserRepository.selectByIds(fofoStores.stream().map(x -> x.getId()).collect(Collectors.toList()));
30982 tejbeer 4755
 
31886 tejbeer 4756
        List<Address> addresses = addressRepository.selectByIds(users.stream().map(x -> x.getAddressId()).collect(Collectors.toList()));
30982 tejbeer 4757
 
31697 amit.gupta 4758
        LOGGER.info("addresses" + addresses);
30984 tejbeer 4759
 
31697 amit.gupta 4760
        for (Address address : addresses) {
32307 amit.gupta 4761
            notificationService.optIn(address.getPhoneNumber());
30982 tejbeer 4762
 
31697 amit.gupta 4763
        }
30982 tejbeer 4764
 
31697 amit.gupta 4765
    }
30982 tejbeer 4766
 
31697 amit.gupta 4767
    public void authUserMobileNumberOptIn() throws HttpHostConnectException, ProfitMandiBusinessException {
31206 tejbeer 4768
 
31697 amit.gupta 4769
        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
4770
        LOGGER.info("authUsers" + authUsers);
31206 tejbeer 4771
 
31697 amit.gupta 4772
        for (AuthUser authUser : authUsers) {
4773
            Map<String, String> requestheaders = new HashMap<>();
4774
            requestheaders.put("Content-Type", "application/x-www-form-urlencoded");
4775
            Map<String, String> requestParams = new HashMap<>();
4776
            requestParams.put("userid", String.valueOf(2000215976));
4777
            requestParams.put("password", "MFRd!BBL");
4778
            requestParams.put("phone_number", authUser.getMobileNumber());
4779
            requestParams.put("auth_scheme", "plain");
4780
            requestParams.put("v", "1.1");
4781
            requestParams.put("format", "json");
31206 tejbeer 4782
 
31697 amit.gupta 4783
            requestParams.put("method", "OPT_IN");
31206 tejbeer 4784
 
31697 amit.gupta 4785
            requestParams.put("channel", "WHATSAPP");
31886 tejbeer 4786
            String response = restClient.get("https://media.smsgupshup.com/GatewayAPI/rest", requestParams, requestheaders);
31697 amit.gupta 4787
            LOGGER.info("response" + response);
4788
        }
31206 tejbeer 4789
 
31697 amit.gupta 4790
    }
31206 tejbeer 4791
 
31697 amit.gupta 4792
    @Autowired
4793
    private HygieneDataRepository hygieneDataRepository;
31209 tejbeer 4794
 
31697 amit.gupta 4795
    public void hygineAlertForPartner() throws ProfitMandiBusinessException, MessagingException, IOException {
31206 tejbeer 4796
 
31697 amit.gupta 4797
        List<String> remarks = new ArrayList<>();
4798
        remarks.add("Out of Service");
4799
        remarks.add("Duplicate number");
4800
        remarks.add("Partner number");
31886 tejbeer 4801
        List<HygieneData> hygieneData = hygieneDataRepository.selectAllByDisposedDateAndRemark(LocalDate.now(), remarks);
31206 tejbeer 4802
 
31697 amit.gupta 4803
        if (!hygieneData.isEmpty()) {
31206 tejbeer 4804
 
31886 tejbeer 4805
            Map<Integer, List<HygieneData>> partnerHygieneDataMap = hygieneData.stream().collect(groupingBy(x -> x.getFofoId()));
31206 tejbeer 4806
 
31697 amit.gupta 4807
            for (Entry<Integer, List<HygieneData>> partnerHygieneDataMapEntry : partnerHygieneDataMap.entrySet()) {
31206 tejbeer 4808
 
31697 amit.gupta 4809
                CustomRetailer customRetailer = retailerService.getFofoRetailer(partnerHygieneDataMapEntry.getKey());
31206 tejbeer 4810
 
31697 amit.gupta 4811
                StringBuilder sb = new StringBuilder();
31886 tejbeer 4812
                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"
31206 tejbeer 4813
 
31886 tejbeer 4814
                        + " </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>"
31206 tejbeer 4815
 
31697 amit.gupta 4816
                        + "<br/><table style='border:1px solid black ;padding: 5px';>");
4817
                sb.append("<tbody>\n" + "	" + "    				" + "<tr>\n");
4818
                sb.append("<th style='border:1px solid black;padding: 5px'>Invoice Number</th>\n");
4819
                sb.append("<th style='border:1px solid black;padding: 5px'>Customer Name</th>\n");
4820
                sb.append("<th style='border:1px solid black;padding: 5px'>Customer Number</th>\n");
4821
                sb.append("</tr>\n");
31206 tejbeer 4822
 
31697 amit.gupta 4823
                List<HygieneData> hygienes = partnerHygieneDataMapEntry.getValue();
31206 tejbeer 4824
 
31697 amit.gupta 4825
                List<Integer> orderIds = hygienes.stream().map(x -> x.getOrderId()).collect(Collectors.toList());
31206 tejbeer 4826
 
31697 amit.gupta 4827
                List<FofoOrder> fofoOrders = fofoOrderRepository.selectAllByOrderIds(orderIds);
31206 tejbeer 4828
 
31697 amit.gupta 4829
                for (FofoOrder fofoOrder : fofoOrders) {
4830
                    Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
4831
                    sb.append("<tr>");
31886 tejbeer 4832
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoOrder.getInvoiceNumber() + "</td>\n");
4833
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + customer.getFirstName() + "" + customer.getLastName() + "</td>\n");
4834
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + customer.getMobileNumber() + "</td>\n");
31206 tejbeer 4835
 
31697 amit.gupta 4836
                    sb.append("</tr>\n");
4837
                }
31206 tejbeer 4838
 
31697 amit.gupta 4839
                sb.append("</tbody></table></body></html>");
4840
                String subject = "Customer Info - Hygiene Alert";
31206 tejbeer 4841
 
36473 amit 4842
                this.sendMailOfHtmlFormat(googleMailSender, new String[]{customRetailer.getEmail()}, sb.toString(), null, subject);
31206 tejbeer 4843
 
31697 amit.gupta 4844
            }
31206 tejbeer 4845
 
31697 amit.gupta 4846
        }
31206 tejbeer 4847
 
31697 amit.gupta 4848
    }
31206 tejbeer 4849
 
33046 amit.gupta 4850
    //
4851
    public void setInventoryItemIdToPriceDropImei() {
4852
        List<PriceDropIMEI> priceDropIMEIList = priceDropIMEIRepository.selectAllMissingInventoryItemIds();
4853
        LOGGER.info("Problems with - {} entries", priceDropIMEIList.size());
4854
        //priceDropIMEIList.stream().collect(C)
4855
        for (PriceDropIMEI priceDropIMEI : priceDropIMEIList) {
4856
            System.out.println(priceDropIMEI.getImei());
4857
            List<InventoryItem> inventoryItems = inventoryItemRepository.selectAllBySerialNumberFofoId(priceDropIMEI.getImei(), priceDropIMEI.getPartnerId());
33051 amit.gupta 4858
            if (inventoryItems.size() == 0) {
33046 amit.gupta 4859
                LOGGER.info("Could not find Grn - FofoID {} , Imei {} ", priceDropIMEI);
33051 amit.gupta 4860
            } else if (inventoryItems.size() > 1) {
33046 amit.gupta 4861
                LOGGER.info("Found 2 such instance for - FofoID {} , Imei {} ", priceDropIMEI.getImei(), priceDropIMEI.getPartnerId());
4862
            } else {
4863
                priceDropIMEI.setInventoryItemId(inventoryItems.get(0).getId());
4864
            }
4865
 
4866
        }
4867
    }
4868
 
33051 amit.gupta 4869
    @Autowired
4870
    SaholicReservationSnapshotRepository saholicReservationSnapshotRepository;
4871
 
33256 amit.gupta 4872
    public void removePartialBillingForTransaction(int transactionId) throws ProfitMandiBusinessException {
35424 amit 4873
        // Fetch with pessimistic lock to prevent concurrent modifications
4874
        List<Order> orderList = orderRepository.selectAllByTransactionIdForUpdate(transactionId);
33051 amit.gupta 4875
        Map<Integer, Order> orderMap = orderList.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
4876
        //Delete scanRecords
4877
        List<WarehouseScan> warehouseScans = warehouseScanRepository.selectAllByOrderIds(new ArrayList<>(orderMap.keySet()));
4878
        for (WarehouseScan warehouseScan : warehouseScans) {
4879
            warehouseScanRepository.delete(warehouseScan);
4880
            WarehouseInventoryItem warehouseInventoryItem = warehouseInventoryItemRepository.selectById(warehouseScan.getInventoryItemId());
4881
            warehouseInventoryItem.setLastScanType(in.shop2020.warehouse.ScanType.PURCHASE);
4882
            warehouseInventoryItem.setCurrentQuantity(warehouseInventoryItem.getCurrentQuantity() + warehouseScan.getQuantity());
4883
        }
4884
 
4885
        for (Order order : orderList) {
33078 ranu 4886
            if (order.getBillingTimestamp() != null) {
33056 amit.gupta 4887
                order.setStatus(OrderStatus.ACCEPTED);
4888
                order.setStatusDescription("Submitted for Processing");
4889
                order.setBillingTimestamp(null);
4890
                order.setBilledBy(null);
33057 amit.gupta 4891
                order.setSerialNumber(null);
33056 amit.gupta 4892
                order.setJacketNumber(null);
33060 amit.gupta 4893
                order.getLineItem().setSerialNumber(null);
33056 amit.gupta 4894
                List<LineItemImei> lineItemImeis = lineItemImeisRepository.selectByLineItemId(order.getLineItem().getId());
4895
                for (LineItemImei lineItemImei : lineItemImeis) {
4896
                    lineItemImeisRepository.delete(lineItemImei);
4897
                }
4898
                SaholicReservationSnapshot saholicReservationSnapshot = saholicReservationSnapshotRepository
4899
                        .selectByOrderId(order.getId());
4900
                if (saholicReservationSnapshot == null) {
4901
                    saholicInventoryService.addReservationCount(order.getLineItem().getItemId(),
4902
                            order.getFulfilmentWarehouseId(), order.getLineItem().getQuantity(), order.getId());
4903
                }
33055 amit.gupta 4904
            }
33051 amit.gupta 4905
        }
4906
    }
4907
 
31697 amit.gupta 4908
    public void hygineAlertForInternalTeam() throws ProfitMandiBusinessException, MessagingException, IOException {
31206 tejbeer 4909
 
31697 amit.gupta 4910
        List<String> remarks = new ArrayList<>();
4911
        remarks.add("Out of Service");
4912
        remarks.add("Duplicate number");
4913
        remarks.add("Partner number");
31886 tejbeer 4914
        List<HygieneData> hygieneDataLastThreeMonth = hygieneDataRepository.selectDisposedDateAndRemarks(
4915
                LocalDate.now().withDayOfMonth(1).minusMonths(3).atStartOfDay(), LocalDate.now().minusMonths(1).withDayOfMonth(LocalDate.now().minusMonths(1).lengthOfMonth()).atTime(LocalTime.MAX), remarks);
31206 tejbeer 4916
 
31886 tejbeer 4917
        List<HygieneData> hygieneDataRecentMonth = hygieneDataRepository.selectDisposedDateAndRemarks(LocalDate.now().withDayOfMonth(1), remarks);
31697 amit.gupta 4918
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
4919
        Map<Integer, List<HygieneData>> partnerHygieneLastThreeMonthMap = null;
31206 tejbeer 4920
 
31697 amit.gupta 4921
        Map<Integer, List<HygieneData>> partnerHygieneDataRecentMonth = null;
31206 tejbeer 4922
 
31697 amit.gupta 4923
        if (!hygieneDataLastThreeMonth.isEmpty()) {
31886 tejbeer 4924
            partnerHygieneLastThreeMonthMap = hygieneDataLastThreeMonth.stream().collect(groupingBy(x -> x.getFofoId()));
31206 tejbeer 4925
 
31697 amit.gupta 4926
        }
31206 tejbeer 4927
 
31697 amit.gupta 4928
        if (!hygieneDataRecentMonth.isEmpty()) {
31886 tejbeer 4929
            partnerHygieneDataRecentMonth = hygieneDataRecentMonth.stream().collect(groupingBy(x -> x.getFofoId()));
31697 amit.gupta 4930
        }
31206 tejbeer 4931
 
31697 amit.gupta 4932
        for (Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {
31206 tejbeer 4933
 
31697 amit.gupta 4934
            String email = storeGuyEntry.getKey();
31206 tejbeer 4935
 
31697 amit.gupta 4936
            List<Integer> fofoIds = new ArrayList<>(storeGuyEntry.getValue());
31206 tejbeer 4937
 
31697 amit.gupta 4938
            Map<Integer, Map<YearMonth, List<HygieneData>>> partnerYearMonthData = new HashMap<>();
4939
            Map<Integer, Map<LocalDate, List<HygieneData>>> partnerDateWiseData = new HashMap<>();
4940
            for (Integer fofoId : fofoIds) {
31206 tejbeer 4941
 
31697 amit.gupta 4942
                partnerYearMonthData.put(fofoId, null);
4943
                partnerDateWiseData.put(fofoId, null);
4944
                if (!partnerHygieneLastThreeMonthMap.isEmpty()) {
4945
                    List<HygieneData> hygienes = partnerHygieneLastThreeMonthMap.get(fofoId);
31206 tejbeer 4946
 
31697 amit.gupta 4947
                    if (hygienes != null) {
31886 tejbeer 4948
                        Map<YearMonth, List<HygieneData>> yearMonthData = hygienes.stream().collect(groupingBy(x -> YearMonth.from(x.getDisposedTimestamp())));
31206 tejbeer 4949
 
31697 amit.gupta 4950
                        partnerYearMonthData.put(fofoId, yearMonthData);
31206 tejbeer 4951
 
31697 amit.gupta 4952
                    }
4953
                    List<HygieneData> dateWiseHygienes = partnerHygieneDataRecentMonth.get(fofoId);
31206 tejbeer 4954
 
31697 amit.gupta 4955
                    if (dateWiseHygienes != null) {
31206 tejbeer 4956
 
31886 tejbeer 4957
                        Map<LocalDate, List<HygieneData>> dateWiseData = hygienes.stream().collect(groupingBy(x -> (x.getDisposedTimestamp()).toLocalDate()));
31206 tejbeer 4958
 
31697 amit.gupta 4959
                        partnerDateWiseData.put(fofoId, dateWiseData);
31206 tejbeer 4960
 
31697 amit.gupta 4961
                    }
31206 tejbeer 4962
 
31697 amit.gupta 4963
                }
31206 tejbeer 4964
 
31697 amit.gupta 4965
            }
31206 tejbeer 4966
 
31697 amit.gupta 4967
            String subject = "Customer Info - Hygiene Alert";
31206 tejbeer 4968
 
31697 amit.gupta 4969
            LOGGER.info("hygieneData {}", partnerDateWiseData.values());
31206 tejbeer 4970
 
31697 amit.gupta 4971
            boolean partnerDateWise = partnerDateWiseData.values().stream().allMatch(Objects::isNull);
31206 tejbeer 4972
 
31697 amit.gupta 4973
            boolean partnerYearMonth = partnerYearMonthData.values().stream().allMatch(Objects::isNull);
31206 tejbeer 4974
 
31697 amit.gupta 4975
            if (!partnerDateWise && !partnerYearMonth) {
4976
                String sb = this.getMessageHygieneAlertForPartner(partnerYearMonthData, partnerDateWiseData);
36460 ranu 4977
                this.sendMailOfHtmlFormat(googleMailSender, new String[]{email}, sb, null, subject);
31697 amit.gupta 4978
            }
31206 tejbeer 4979
 
31697 amit.gupta 4980
        }
31206 tejbeer 4981
 
31697 amit.gupta 4982
    }
31206 tejbeer 4983
 
31697 amit.gupta 4984
    private String getMessageHygieneAlertForPartner(
33256 amit.gupta 4985
            Map<Integer, Map<YearMonth, List<HygieneData>>> partnerYearMonthData, Map<Integer, Map<LocalDate, List<HygieneData>>> partnerDateWiseData)
4986
            throws ProfitMandiBusinessException {
31206 tejbeer 4987
 
31697 amit.gupta 4988
        Map<Integer, CustomRetailer> customeRetailerMap = retailerService.getAllFofoRetailers();
31206 tejbeer 4989
 
31697 amit.gupta 4990
        LocalDateTime startDate = LocalDate.now().withDayOfMonth(1).atStartOfDay();
4991
        LocalDateTime endDate = LocalDateTime.now();
31206 tejbeer 4992
 
31697 amit.gupta 4993
        LocalDateTime startYearMonth = LocalDate.now().withDayOfMonth(1).minusMonths(3).atStartOfDay();
31886 tejbeer 4994
        LocalDateTime endYearMonth = LocalDate.now().minusMonths(1).withDayOfMonth(LocalDate.now().minusMonths(1).lengthOfMonth()).atTime(LocalTime.MAX);
31206 tejbeer 4995
 
31697 amit.gupta 4996
        DateTimeFormatter dateYearMonthFormatter = DateTimeFormatter.ofPattern("MMM''uu");
31206 tejbeer 4997
 
31697 amit.gupta 4998
        List<YearMonth> yearMonthRange = new ArrayList<>();
4999
        yearMonthRange.add(YearMonth.from(startYearMonth));
31206 tejbeer 5000
 
31697 amit.gupta 5001
        yearMonthRange.add(YearMonth.from(startYearMonth.plusMonths(1)));
31206 tejbeer 5002
 
31697 amit.gupta 5003
        yearMonthRange.add(YearMonth.from(endYearMonth));
31206 tejbeer 5004
 
31697 amit.gupta 5005
        long noOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate.plusDays(1));
31206 tejbeer 5006
 
31886 tejbeer 5007
        List<LocalDate> dateRange = Stream.iterate(startDate.toLocalDate(), date -> date.plusDays(1)).limit(noOfDaysBetween).collect(Collectors.toList());
31206 tejbeer 5008
 
31697 amit.gupta 5009
        StringBuilder sb = new StringBuilder();
31886 tejbeer 5010
        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>"
31206 tejbeer 5011
 
31697 amit.gupta 5012
                + "<table style='border:1px solid black ;padding: 5px';>");
5013
        sb.append("<tbody>\n" + "	" + "    				" + "<tr>\n");
5014
        sb.append("<th style='border:1px solid black;padding: 5px'>Partner Name</th>\n");
31206 tejbeer 5015
 
31697 amit.gupta 5016
        for (YearMonth yearMonth : yearMonthRange) {
31886 tejbeer 5017
            sb.append("<th style='border:1px solid black;padding: 5px'>" + yearMonth.format(dateYearMonthFormatter) + "</th>\n");
31697 amit.gupta 5018
        }
31206 tejbeer 5019
 
31697 amit.gupta 5020
        for (LocalDate localDate : dateRange) {
5021
            sb.append("<th style='border:1px solid black;padding: 5px'>" + localDate + "</th>\n");
5022
        }
31206 tejbeer 5023
 
31697 amit.gupta 5024
        sb.append("</tr>\n");
31206 tejbeer 5025
 
31886 tejbeer 5026
        for (Entry<Integer, Map<YearMonth, List<HygieneData>>> partnerYearMonthEntry : partnerYearMonthData.entrySet()) {
31206 tejbeer 5027
 
31697 amit.gupta 5028
            int fofoId = partnerYearMonthEntry.getKey();
31206 tejbeer 5029
 
31697 amit.gupta 5030
            Map<YearMonth, List<HygieneData>> yearMonthData = partnerYearMonthEntry.getValue();
31206 tejbeer 5031
 
31697 amit.gupta 5032
            Map<LocalDate, List<HygieneData>> dateWiseData = partnerDateWiseData.get(fofoId);
31206 tejbeer 5033
 
31697 amit.gupta 5034
            if (yearMonthData == null && dateWiseData == null) {
5035
                continue;
5036
            }
31206 tejbeer 5037
 
31697 amit.gupta 5038
            sb.append("<tr>");
31886 tejbeer 5039
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customeRetailerMap.get(fofoId).getBusinessName() + "</td>\n");
31697 amit.gupta 5040
            for (YearMonth yearMonth : yearMonthRange) {
31206 tejbeer 5041
 
31697 amit.gupta 5042
                if (yearMonthData == null) {
5043
                    sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");
31206 tejbeer 5044
 
31697 amit.gupta 5045
                } else {
5046
                    List<HygieneData> hygieneList = yearMonthData.get(yearMonth);
31206 tejbeer 5047
 
31697 amit.gupta 5048
                    if (hygieneList != null) {
5049
                        sb.append("<td style='border:1px solid black;padding: 5px'>" + hygieneList.size() + "</td>\n");
31206 tejbeer 5050
 
31697 amit.gupta 5051
                    } else {
5052
                        sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");
31206 tejbeer 5053
 
31697 amit.gupta 5054
                    }
5055
                }
5056
            }
31206 tejbeer 5057
 
31697 amit.gupta 5058
            for (LocalDate localDate : dateRange) {
31206 tejbeer 5059
 
31697 amit.gupta 5060
                if (dateWiseData == null) {
5061
                    sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");
31206 tejbeer 5062
 
31697 amit.gupta 5063
                } else {
5064
                    List<HygieneData> hygieneList = dateWiseData.get(localDate);
31206 tejbeer 5065
 
31697 amit.gupta 5066
                    if (hygieneList != null) {
5067
                        sb.append("<td style='border:1px solid black;padding: 5px'>" + hygieneList.size() + "</td>\n");
31218 tejbeer 5068
 
31697 amit.gupta 5069
                    } else {
5070
                        sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");
31218 tejbeer 5071
 
31697 amit.gupta 5072
                    }
5073
                }
5074
            }
5075
            sb.append("</tr>");
31218 tejbeer 5076
 
31697 amit.gupta 5077
        }
31218 tejbeer 5078
 
31697 amit.gupta 5079
        sb.append("</tbody></table></body></html>");
31218 tejbeer 5080
 
31697 amit.gupta 5081
        return sb.toString();
5082
    }
31218 tejbeer 5083
 
33874 ranu 5084
    @Autowired
5085
    private MonthlyTargetRepository monthlyTargetRepository;
31218 tejbeer 5086
 
31697 amit.gupta 5087
    public void monthlyTargetForPartner() throws MessagingException, ProfitMandiBusinessException, IOException {
31218 tejbeer 5088
 
31697 amit.gupta 5089
        LocalDateTime curDate = LocalDateTime.now();
5090
        List<MonthlyTarget> monthlyTargets = monthlyTargetRepository.selectByDate(YearMonth.now());
31218 tejbeer 5091
 
31886 tejbeer 5092
        Map<Integer, MonthlyTarget> partnersMonthlyTarget = monthlyTargets.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
31218 tejbeer 5093
 
31886 tejbeer 5094
        Map<Integer, Double> secondaryMtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));
5095
        Map<Integer, Double> todaytertiary = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate, curDate.with(LocalTime.MAX), 0, false);
31218 tejbeer 5096
 
31697 amit.gupta 5097
        String subject = "Monthly Target Vs Achievement";
31218 tejbeer 5098
 
31697 amit.gupta 5099
        for (Entry<Integer, MonthlyTarget> partnerMonthlyTargetEntry : partnersMonthlyTarget.entrySet()) {
31249 tejbeer 5100
 
31697 amit.gupta 5101
            int fofoId = partnerMonthlyTargetEntry.getKey();
31249 tejbeer 5102
 
31697 amit.gupta 5103
            CustomRetailer customRetailer = retailerService.getFofoRetailer(fofoId);
31249 tejbeer 5104
 
31697 amit.gupta 5105
            Double purchaseTarget = partnerMonthlyTargetEntry.getValue().getPurchaseTarget();
31218 tejbeer 5106
 
31697 amit.gupta 5107
            Double saleTarget = partnerMonthlyTargetEntry.getValue().getSaleTarget();
31218 tejbeer 5108
 
31697 amit.gupta 5109
            if (purchaseTarget > 0) {
5110
                Double purchase = secondaryMtd.get(fofoId);
31249 tejbeer 5111
 
31697 amit.gupta 5112
                if (purchase == null) {
5113
                    purchase = 0.0;
5114
                }
31218 tejbeer 5115
 
31697 amit.gupta 5116
                Double balanceTarget = purchaseTarget - purchase;
31218 tejbeer 5117
 
31697 amit.gupta 5118
                if (balanceTarget <= 0) {
5119
                    balanceTarget = 0.0;
5120
                }
31651 tejbeer 5121
 
31697 amit.gupta 5122
                StringBuilder sb = new StringBuilder();
5123
                sb.append("<html><body><p>Dear Partner,\n");
31886 tejbeer 5124
                sb.append("<p>Pls note your agreed monthly target is Rs." + purchaseTarget + " and your achievement till date is Rs." + purchase + "</p>");
31697 amit.gupta 5125
                sb.append("<p>Pls note that your balance target is Rs." + balanceTarget + "</p>\n");
5126
                sb.append(
32350 amit.gupta 5127
                        "<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");
31651 tejbeer 5128
 
36473 amit 5129
                this.sendMailOfHtmlFormat(googleMailSender, new String[]{customRetailer.getEmail()}, sb.toString(), null, subject);
31697 amit.gupta 5130
            }
31218 tejbeer 5131
 
31697 amit.gupta 5132
        }
31218 tejbeer 5133
 
31697 amit.gupta 5134
    }
31218 tejbeer 5135
 
33444 ranu 5136
 
34502 amit.gupta 5137
    public void findAllLiveDemoBrandItemsByBillingDate() throws
5138
            MessagingException, ProfitMandiBusinessException, IOException {
33444 ranu 5139
        LocalDateTime endDate = LocalDate.now().atStartOfDay().minusDays(8);
5140
 
5141
        List<LiveDemoOrderLineItemModel> liveDemoOrderLineItemModels = orderRepository.findAllLiveDemoBrandItemsByBillingDate(endDate.minusDays(60), endDate);
5142
        LOGGER.info("liveDemoOrderLineItemModels {}", liveDemoOrderLineItemModels);
5143
        String subject = "Billed Live Demo Model";
5144
        StringBuilder sb = new StringBuilder();
5145
 
5146
        sb.append("<html><body><p>Hi,\n");
5147
        sb.append("<p>Please check live demo billed order :</p>\n" + " <table style='border:1px solid black ;padding: 5px; border-collapse: collapse;'>");
5148
 
5149
        sb.append("<th style='border:1px solid black;padding: 5px'>Item Id</th>\n");
5150
        sb.append("<th style='border:1px solid black;padding: 5px'>Invoice Number</th>\n");
5151
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
5152
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
5153
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
5154
        sb.append("<th style='border:1px solid black;padding: 5px'>Serial Number</th>\n");
5155
        sb.append("<th style='border:1px solid black;padding: 5px'>Retailer Name</th>\n");
5156
        sb.append("<th style='border:1px solid black;padding: 5px'>Retailer City</th>\n");
5157
        sb.append("<th style='border:1px solid black;padding: 5px'>Retailer Pincode</th>\n");
5158
        sb.append("<th style='border:1px solid black;padding: 5px'>Retailer State</th>\n");
5159
        sb.append("<th style='border:1px solid black;padding: 5px'>Billing Date</th>\n");
5160
        sb.append("</tr>\n");
5161
        for (LiveDemoOrderLineItemModel liveDemoModel : liveDemoOrderLineItemModels) {
5162
            sb.append("<tr>");
5163
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getItemId() + "</td>\n");
5164
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getInvoiceNumber() + "</td>\n");
5165
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getBrand() + "</td>\n");
5166
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getModelNumber() + "</td>\n");
5167
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getModelName() + "</td>\n");
5168
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getSerialNumber() + "</td>\n");
5169
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getRetailerName() + "</td>\n");
5170
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getRetailerCity() + "</td>\n");
5171
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getRetailerPincode() + "</td>\n");
5172
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getState() + "</td>\n");
5173
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getFormattedBillingDate() + "</td>\n");
5174
 
5175
            sb.append("</tr>\n");
5176
 
33506 amit.gupta 5177
        }
33444 ranu 5178
        List<String> sendTo = Arrays.asList("kamini.sharma@smartdukaan.com", "niranjan.kala@smartdukaan.com",
33506 amit.gupta 5179
                "mohit.gulati@smartdukaan.com", "vinay.p@smartdukaan.com", "shivam.gupta@smartdukaan.com");
33444 ranu 5180
 
5181
 
5182
        String[] email = sendTo.toArray(new String[sendTo.size()]);
36476 amit 5183
    this.sendMailOfHtmlFormat(googleMailSender, email, sb.toString(), null, subject);
33444 ranu 5184
 
5185
    }
5186
 
33464 ranu 5187
    public void findTodayPocoBillingItems() throws MessagingException, ProfitMandiBusinessException, IOException {
5188
        LocalDateTime endDate = LocalDate.now().atStartOfDay().plusDays(1);
5189
        LocalDateTime startDate = LocalDate.now().atStartOfDay().minusDays(1);
33444 ranu 5190
 
33464 ranu 5191
        List<LiveDemoOrderLineItemModel> pocoBillingOrderLineItemModels = orderRepository.findTodayPocoBillingItems(startDate, endDate);
5192
        LOGGER.info("pocoBillingOrderLineItemModels {}", pocoBillingOrderLineItemModels);
5193
        String subject = "Poco Billing";
5194
        StringBuilder sb = new StringBuilder();
5195
 
5196
        sb.append("<html><body><p>Hi,\n");
5197
        sb.append("<p>Please check poco billed order :</p>\n" + " <table style='border:1px solid black ;padding: 5px; border-collapse: collapse;'>");
5198
 
5199
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
5200
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
5201
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
5202
        sb.append("<th style='border:1px solid black;padding: 5px'>Serial Number</th>\n");
5203
        sb.append("<th style='border:1px solid black;padding: 5px'>Retailer State</th>\n");
5204
        sb.append("<th style='border:1px solid black;padding: 5px'>Billing Date</th>\n");
5205
        sb.append("</tr>\n");
5206
        for (LiveDemoOrderLineItemModel pocoModel : pocoBillingOrderLineItemModels) {
5207
            sb.append("<tr>");
5208
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getBrand() + "</td>\n");
5209
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getModelNumber() + "</td>\n");
5210
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getModelName() + "</td>\n");
5211
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getSerialNumber() + "</td>\n");
5212
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getState() + "</td>\n");
5213
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getFormattedBillingDate() + "</td>\n");
5214
 
5215
            sb.append("</tr>\n");
5216
 
33506 amit.gupta 5217
        }
36936 vikas 5218
        List<String> sendTo = Arrays.asList("uday.singh@smartdukaan.com", "kuldeep.kumar@smartdukaan.com", "ritesh.chauhan1@smartdukaan.com");
33464 ranu 5219
 
5220
        String[] email = sendTo.toArray(new String[sendTo.size()]);
36473 amit 5221
        this.sendMailOfHtmlFormat(googleMailSender, email, sb.toString(), null, subject);
33464 ranu 5222
 
5223
    }
5224
 
5225
 
31697 amit.gupta 5226
    public void monthlyTargetForInternalTeam() throws MessagingException, ProfitMandiBusinessException, IOException {
31218 tejbeer 5227
 
31697 amit.gupta 5228
        LocalDateTime curDate = LocalDateTime.now();
31218 tejbeer 5229
 
34903 ranu 5230
        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);
31218 tejbeer 5231
 
31697 amit.gupta 5232
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false);
31218 tejbeer 5233
 
31697 amit.gupta 5234
        List<MonthlyTarget> monthlyTargets = monthlyTargetRepository.selectByDate(YearMonth.now());
31218 tejbeer 5235
 
31697 amit.gupta 5236
        Map<Integer, CustomRetailer> customeRetailerMap = retailerService.getAllFofoRetailers();
31218 tejbeer 5237
 
31886 tejbeer 5238
        Map<Integer, MonthlyTarget> partnersMonthlyTarget = monthlyTargets.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
31218 tejbeer 5239
 
31886 tejbeer 5240
        Map<Integer, Double> secondaryMtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));
5241
        Map<Integer, Double> todaytertiary = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate, curDate.with(LocalTime.MAX), 0, false);
31218 tejbeer 5242
 
31697 amit.gupta 5243
        String subject = "Monthly Target Vs Achievement";
31218 tejbeer 5244
 
31697 amit.gupta 5245
        for (Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {
31218 tejbeer 5246
 
31697 amit.gupta 5247
            String email = storeGuyEntry.getKey();
31218 tejbeer 5248
 
31697 amit.gupta 5249
            List<Integer> fofoIds = new ArrayList<>(storeGuyEntry.getValue());
5250
            Map<Integer, MonthlyTarget> monthlyTargetAchievement = new HashMap<>();
5251
            for (Integer fofoId : fofoIds) {
31218 tejbeer 5252
 
31697 amit.gupta 5253
                MonthlyTarget monthlyTarget = partnersMonthlyTarget.get(fofoId);
5254
                if (monthlyTarget != null) {
5255
                    Double purchaseTarget = monthlyTarget.getPurchaseTarget();
31218 tejbeer 5256
 
31697 amit.gupta 5257
                    Double saleTarget = monthlyTarget.getSaleTarget();
31218 tejbeer 5258
 
31697 amit.gupta 5259
                    if (purchaseTarget != null && purchaseTarget > 0) {
5260
                        Double purchase = secondaryMtd.get(fofoId);
5261
                        if (purchase == null) {
5262
                            purchase = 0.0;
5263
                        }
5264
                        monthlyTarget.setPurchaseAchievement(purchase);
5265
                        monthlyTargetAchievement.put(fofoId, monthlyTarget);
31218 tejbeer 5266
 
31697 amit.gupta 5267
                    }
5268
                }
5269
            }
31218 tejbeer 5270
 
31697 amit.gupta 5271
            if (!monthlyTargetAchievement.isEmpty()) {
31218 tejbeer 5272
 
31697 amit.gupta 5273
                StringBuilder sb = new StringBuilder();
31218 tejbeer 5274
 
31697 amit.gupta 5275
                sb.append("<html><body><p>Hi,\n");
31886 tejbeer 5276
                sb.append("<p>Pls note your Partners agreed monthly target foolowing are :</p>\n" + " <table style='border:1px solid black ;padding: 5px';>");
31697 amit.gupta 5277
                sb.append("<tbody>\n" + "	" + "    				" + "<tr>\n");
5278
                sb.append("<th style='border:1px solid black;padding: 5px'>Partner Name</th>\n");
31218 tejbeer 5279
 
31697 amit.gupta 5280
                sb.append("<th style='border:1px solid black;padding: 5px'>Purchase Target</th>\n");
31218 tejbeer 5281
 
31697 amit.gupta 5282
                sb.append("<th style='border:1px solid black;padding: 5px'>Purchase Achievement</th>\n");
5283
                sb.append("</tr>\n");
31218 tejbeer 5284
 
31886 tejbeer 5285
                for (Entry<Integer, MonthlyTarget> monthlyTargetAchievementEntry : monthlyTargetAchievement.entrySet()) {
31697 amit.gupta 5286
                    sb.append("<tr>");
5287
                    int fofoId = monthlyTargetAchievementEntry.getKey();
31218 tejbeer 5288
 
31697 amit.gupta 5289
                    MonthlyTarget monthlyTarget = monthlyTargetAchievementEntry.getValue();
31886 tejbeer 5290
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + customeRetailerMap.get(fofoId).getBusinessName() + "</td>\n");
31218 tejbeer 5291
 
31886 tejbeer 5292
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + monthlyTarget.getPurchaseTarget() + "</td>\n");
31218 tejbeer 5293
 
31886 tejbeer 5294
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + monthlyTarget.getPurchaseAchievement() + "</td>\n");
31218 tejbeer 5295
 
31697 amit.gupta 5296
                    sb.append("</tr>\n");
31218 tejbeer 5297
 
31697 amit.gupta 5298
                }
31218 tejbeer 5299
 
36460 ranu 5300
                this.sendMailOfHtmlFormat(googleMailSender, new String[]{email}, sb.toString(), null, subject);
31697 amit.gupta 5301
                // this.sendMailOfHtmlFormat("tejbeer.kaur@smartdukaan.com", sb.toString(),
5302
                // null, subject);
31218 tejbeer 5303
 
31697 amit.gupta 5304
            }
31604 tejbeer 5305
 
31697 amit.gupta 5306
        }
31604 tejbeer 5307
 
31697 amit.gupta 5308
    }
31604 tejbeer 5309
 
32061 amit.gupta 5310
    @Autowired
5311
    private PerformanceService performanceService;
5312
 
5313
 
5314
    public void sendFilteredRetailerPerformance() throws Exception {
5315
        RetailerFilterModel retailerFilterModel = performanceService.getRetailerFilterModel();
5316
 
5317
        Map<Integer, CustomRetailer> customRetailers = retailerService.getFofoRetailers(true);
5318
 
5319
 
5320
        List<RetailerPeformanceFilterModel> partnersPerformance = performanceService.getPerformance(retailerFilterModel, customRetailers);
5321
 
5322
        Map<Integer, RetailerPeformanceFilterModel> partnersPerformanceMap = new HashMap<>();
5323
 
5324
        if (!partnersPerformance.isEmpty()) {
5325
            partnersPerformanceMap = partnersPerformance.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
5326
            performanceService.sendPartnerPerformanceEmail(partnersPerformanceMap, retailerFilterModel, customRetailers);
5327
 
5328
        }
5329
 
5330
 
5331
    }
5332
 
32081 tejbeer 5333
    @Autowired
5334
    private VendorItemPricingRepository vendorItemPricingRepository;
32061 amit.gupta 5335
 
32081 tejbeer 5336
 
5337
    @Autowired
5338
    private VendorCatalogPricingService vendorCatalogPricingService;
5339
 
5340
 
33256 amit.gupta 5341
    public void migrateVendorItemPricing() throws ProfitMandiBusinessException {
32081 tejbeer 5342
 
5343
        List<VendorItemPricing> vendorItemPricings = vendorItemPricingRepository.selectAll();
32350 amit.gupta 5344
        LOGGER.info("At migrate VendorItemPricing");
32092 tejbeer 5345
        Map<Integer, Item> items = itemRepository.selectByIds(vendorItemPricings.stream().map(x -> x.getItemId()).collect(Collectors.toSet())).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
32081 tejbeer 5346
        for (VendorItemPricing vendorItemPricing : vendorItemPricings) {
5347
            Item item = null;
32092 tejbeer 5348
            if (items.get(vendorItemPricing.getItemId()) != null) {
5349
                item = items.get(vendorItemPricing.getItemId());
5350
            } else {
32084 tejbeer 5351
                continue;
32081 tejbeer 5352
            }
32092 tejbeer 5353
 
32081 tejbeer 5354
            VendorCatalogPricingModel vendorCatalogPricingModel = new VendorCatalogPricingModel();
5355
            vendorCatalogPricingModel.setCatalogId(item.getCatalogItemId());
5356
            vendorCatalogPricingModel.setAuthId(13);
32088 tejbeer 5357
            vendorCatalogPricingModel.setDp(vendorItemPricing.getDp());
32081 tejbeer 5358
 
5359
            vendorCatalogPricingModel.setTp(vendorItemPricing.getTp());
5360
            vendorCatalogPricingModel.setMop(vendorItemPricing.getMop());
32384 amit.gupta 5361
            vendorCatalogPricingModel.setEffectedOn(LocalDate.of(2023, 8, 22));
32081 tejbeer 5362
            vendorCatalogPricingModel.setVendorId(vendorItemPricing.getVendorId());
5363
 
5364
 
5365
            try {
5366
                vendorCatalogPricingService.createVendorCatalogPricingLog(vendorCatalogPricingModel);
5367
            } catch (ProfitMandiBusinessException e) {
5368
                continue;
5369
            }
5370
 
5371
        }
5372
 
5373
    }
5374
 
5375
    public void approveVendorCatalogPricing() {
5376
        List<VendorCatalogPricingLog> vendorCatalogPricingLogs = vendorCatalogPricingLogRepository.selectByStatus(VendorCatalogPricingStatus.PENDING);
5377
 
32084 tejbeer 5378
 
32081 tejbeer 5379
        for (VendorCatalogPricingLog vendorCatalogPricingLog : vendorCatalogPricingLogs) {
32107 tejbeer 5380
            vendorCatalogPricingLog.setStatus(VendorCatalogPricingStatus.APPROVED);
5381
            vendorCatalogPricingLog.setUpdatedTimestamp(LocalDateTime.now());
5382
            vendorCatalogPricingLog.setApprovedBy(13);
5383
            vendorCatalogPricingLog.setApprovedTimestamp(LocalDateTime.now());
32114 tejbeer 5384
            vendorCatalogPricingService.createVendorCatalogPricing(vendorCatalogPricingLog);
5385
        }
32081 tejbeer 5386
 
32114 tejbeer 5387
    }
32108 tejbeer 5388
 
32822 ranu 5389
    public void sendMailWhatsAppAfterLoanDueDate() throws Exception {
36289 amit 5390
        synchronized (SD_CREDIT_LOCK) {
5391
            sdCreditService.updateRisk();
5392
            List<Loan> defaultLoans = sdCreditService.getDefaultLoans();
5393
            if (!defaultLoans.isEmpty()) {
5394
                this.sendLoanAlert(defaultLoans);
5395
            }
32822 ranu 5396
        }
5397
    }
5398
 
5399
    public void sendLoanAlert(List<Loan> defaultLoans) throws
5400
            Exception {
5401
 
35877 amit 5402
        // Sort by lowest dueDate first (most overdue)
5403
        defaultLoans.sort(Comparator.comparing(Loan::getDueDate));
32822 ranu 5404
 
32842 amit.gupta 5405
        String title = "SD Credit Alert!";
35877 amit 5406
        int whatsAppCount = 0;
32822 ranu 5407
        for (Loan defaultLoan : defaultLoans) {
35877 amit 5408
            double principal = defaultLoan.getPendingAmount().doubleValue();
5409
            double interest = defaultLoan.getInterestAccrued().doubleValue() - defaultLoan.getInterestPaid().doubleValue();
5410
            double total = principal + interest;
32822 ranu 5411
 
5412
            com.spice.profitmandi.dao.entity.user.User user = userUserRepository.selectById(defaultLoan.getFofoId());
5413
 
5414
            Address address = addressRepository.selectById(user.getAddressId());
5415
 
35877 amit 5416
            // WhatsApp: only top 2 most overdue loans
5417
            if (whatsAppCount < 2) {
5418
                String whatsAppMessage = getWhatsAppMessageForDefaultLoan(defaultLoan, total, user.getName());
32850 amit.gupta 5419
                notificationService.sendWhatsappMessage(whatsAppMessage, title, address.getPhoneNumber());
35877 amit 5420
                whatsAppCount++;
32850 amit.gupta 5421
            }
5422
 
35877 amit 5423
            String emailMessage = getEmailMessageForDefaultLoan(defaultLoan, principal, interest, total, user.getName());
32822 ranu 5424
            String[] email = {user.getEmailId()};
36473 amit 5425
            sendMailOfHtmlFormat(googleMailSender, email, emailMessage, null, "Loan Alert - SmartDukaan");
32822 ranu 5426
        }
5427
    }
5428
 
35877 amit 5429
    private String getEmailMessageForDefaultLoan(Loan loan, double principal, double interest, double total, String name) {
5430
        String formattedTotal = FormattingUtils.formatDecimal(total);
5431
        String formattedPrincipal = FormattingUtils.formatDecimal(principal);
5432
        String formattedInterest = FormattingUtils.formatDecimal(interest);
5433
        long daysInDefault = ChronoUnit.DAYS.between(loan.getPenaltyDate(), LocalDate.now());
32822 ranu 5434
 
5435
        StringBuilder sb = new StringBuilder();
35877 amit 5436
        sb.append("<html><body>");
5437
        sb.append("<p><b>Credit Default Alert!</b></p><br/>");
5438
        sb.append("<p>Dear " + name + ",</p>");
5439
        sb.append("<p>Your credit payment has been in default for " + daysInDefault + " days. " +
35915 amit 5440
                "A penalty interest of " + (loan.getPenaltyRate() != null ? loan.getPenaltyRate() : ProfitMandiConstants.NEW_DELAYED_INTEREST_RATE) + "% per day is being charged.</p>");
35877 amit 5441
        sb.append("<p><b>Total Outstanding: Rs. " + formattedTotal + "</b><br/>");
5442
        sb.append("Principal: Rs. " + formattedPrincipal + "<br/>");
5443
        sb.append("Interest: Rs. " + formattedInterest + "</p>");
5444
        sb.append("<p>Continued default will impact your Credit score and may result in legal action. " +
5445
                "Please settle the outstanding amount immediately.</p>");
5446
        sb.append("<p>To make the payment, please add Rs. " + formattedTotal + " to your wallet.</p>");
5447
        sb.append("<p>Team SmartDukaan</p>");
32822 ranu 5448
        sb.append("</body></html>");
5449
        return sb.toString();
5450
    }
5451
 
35877 amit 5452
    private String getWhatsAppMessageForDefaultLoan(Loan loan, double total, String name) {
5453
        String formattedAmount = FormattingUtils.formatDecimal(total);
5454
        long daysInDefault = ChronoUnit.DAYS.between(loan.getPenaltyDate(), LocalDate.now());
32822 ranu 5455
 
35877 amit 5456
        return String.format(
5457
                "Dear %s, Your credit payment has been in default for %d days. " +
5458
                "A penalty interest of %s%% per day is being charged on your outstanding amount of Rs. %s. " +
5459
                "Please settle immediately to avoid legal action.\n\nTeam SmartDukaan",
35915 amit 5460
                name, daysInDefault, loan.getPenaltyRate() != null ? loan.getPenaltyRate() : ProfitMandiConstants.NEW_DELAYED_INTEREST_RATE, formattedAmount);
32822 ranu 5461
    }
5462
 
33874 ranu 5463
    @Autowired
5464
    private FofoOpeningStockRepository fofoOpeningStockRepository;
34450 ranu 5465
    @Autowired
5466
    private SmartCartService smartCartService;
33874 ranu 5467
 
5468
    public void createOpeningStockPartyWise() throws Exception {
5469
        // Get all partner stock data
35329 ranu 5470
        Map<Integer, List<PartnerOpeningStockByTodayModel>> partnerOpeningStockByTodayInStockMap = currentInventorySnapshotRepository.getAllPartnerTodayInstock();
5471
        Map<Integer, List<PartnerOpeningStockByTodayModel>> partnerOpeningStockByTodayGrnPending = currentInventorySnapshotRepository.getAllPartnerTodayGrnPending();
5472
 
5473
        Map<Integer, List<PartnerOpeningStockByTodayModel>> partnerOpeningStockByTodayMap =
5474
                new HashMap<>();
5475
 
5476
// STEP 1: Copy in-stock data
5477
        partnerOpeningStockByTodayInStockMap.forEach((fofoId, list) ->
5478
                partnerOpeningStockByTodayMap.put(
5479
                        fofoId,
5480
                        new ArrayList<>(list)   // deep list copy
5481
                )
5482
        );
5483
 
5484
// STEP 2: Merge GRN pending using streams
5485
        partnerOpeningStockByTodayGrnPending.forEach((fofoId, grnList) -> {
5486
 
5487
            // If FOFO missing → simply insert GRN list (deep copy)
5488
            partnerOpeningStockByTodayMap
5489
                    .computeIfAbsent(fofoId, x -> new ArrayList<>())
5490
                    .addAll(
5491
                            grnList.stream()
5492
                                    .map(g -> new PartnerOpeningStockByTodayModel(
5493
                                            g.getFofoId(),
5494
                                            g.getCatalogId(),
5495
                                            g.getModelNumber(),
5496
                                            g.getOpeningQty()
5497
                                    ))
5498
                                    .collect(Collectors.toList())
5499
                    );
5500
        });
5501
 
5502
// STEP 3: Now merge duplicates per catalogId using grouping
5503
        partnerOpeningStockByTodayMap.replaceAll((fofoId, list) ->
5504
                list.stream()
5505
                        .collect(Collectors.toMap(
5506
                                PartnerOpeningStockByTodayModel::getCatalogId,
5507
                                m -> new PartnerOpeningStockByTodayModel(
5508
                                        m.getFofoId(),
5509
                                        m.getCatalogId(),
5510
                                        m.getModelNumber(),
5511
                                        m.getOpeningQty()
5512
                                ),
5513
                                // merge function: sum openingQty
5514
                                (m1, m2) -> {
5515
                                    m1.setOpeningQty(m1.getOpeningQty() + m2.getOpeningQty());
5516
                                    return m1;
5517
                                }
5518
                        ))
5519
                        .values()
5520
                        .stream()
5521
                        .collect(Collectors.toList())
5522
        );
5523
 
5524
 
34460 ranu 5525
        Map<Integer, Map<Integer, Integer>> activatedButNotBilledCatalogQtyMap = smartCartService.activatedButNotBilledCatalogQtyMap();
34502 amit.gupta 5526
        LOGGER.info("PartnerOpeningStockByTodayModel {}", partnerOpeningStockByTodayMap);
33874 ranu 5527
        for (Map.Entry<Integer, List<PartnerOpeningStockByTodayModel>> entry : partnerOpeningStockByTodayMap.entrySet()) {
5528
            int fofoId = entry.getKey();
5529
            List<PartnerOpeningStockByTodayModel> partnerStockList = entry.getValue();
34450 ranu 5530
            // Get the sold (activated-but-not-billed) quantity for this fofo and catalog
34460 ranu 5531
            Map<Integer, Integer> activatedButNotBilledQtyMap = activatedButNotBilledCatalogQtyMap.getOrDefault(fofoId, Collections.emptyMap());
33874 ranu 5532
 
34450 ranu 5533
            //  if stock is avaialble in snapshot
33874 ranu 5534
            for (PartnerOpeningStockByTodayModel partnerStock : partnerStockList) {
5535
                int catalogId = partnerStock.getCatalogId();
34450 ranu 5536
                int stockCurrentQty = partnerStock.getOpeningQty();
33874 ranu 5537
                LocalDate openingDate = partnerStock.getOpeningDate();
5538
 
34460 ranu 5539
                int soldButNotBilledQty = activatedButNotBilledQtyMap.getOrDefault(catalogId, 0);
34450 ranu 5540
 
35521 amit 5541
                if (catalogId == 1025656 && fofoId == 175140232) {
5542
                    LOGGER.info("catalogId {}", catalogId);
5543
                    LOGGER.info("fofoId {}", fofoId);
5544
                    LOGGER.info("soldButNotBilledQty {}", soldButNotBilledQty);
5545
                    LOGGER.info("stockCurrentQty {}", stockCurrentQty);
35329 ranu 5546
                }
5547
 
34450 ranu 5548
                // Subtract soldQty from partnerCurrentQty
34460 ranu 5549
                int partnerCurrentQty = Math.max(stockCurrentQty - soldButNotBilledQty, 0); // Ensure it doesn't go negative
34450 ranu 5550
 
5551
 
33874 ranu 5552
                // Check if an entry already exists in the FofoOpeningStock table
5553
                FofoOpeningStock existingStock = fofoOpeningStockRepository.findByFofoIdAndCatalogId(fofoId, catalogId);
5554
 
34162 ranu 5555
 
33874 ranu 5556
                if (existingStock != null) {
34363 ranu 5557
                    if (partnerCurrentQty < 1 && existingStock.getOpeningDate().isBefore(LocalDate.now().minusDays(5))) {
34160 tejus.loha 5558
                        fofoOpeningStockRepository.delete(existingStock);
5559
                    }
34162 ranu 5560
                    if (existingStock.getOpeningQty() < partnerCurrentQty) {
5561
                        existingStock.setOpeningQty(partnerCurrentQty);
5562
                        existingStock.setCurrentQty(partnerCurrentQty);
33874 ranu 5563
                        existingStock.setOpeningDate(openingDate);
5564
                        LOGGER.info("if condition exist {}");
34275 tejus.loha 5565
                    } else if (existingStock.getCurrentQty() >= existingStock.getOpeningQty()) {
5566
                        existingStock.setOpeningQty(existingStock.getCurrentQty());
5567
                        existingStock.setCurrentQty(partnerCurrentQty);
5568
                        existingStock.setOpeningDate(LocalDate.now());
34363 ranu 5569
                    } else if (existingStock.getOpeningDate().isBefore(LocalDate.now().minusDays(5))) {
33878 ranu 5570
                        int averageQty = Math.round((existingStock.getCurrentQty() + existingStock.getOpeningQty()) / 2.0f);
5571
 
5572
                        if (averageQty == 1 && existingStock.getOpeningQty() == 1 && existingStock.getCurrentQty() == 0) {
5573
                            // Delete the existing stock entry from the table
5574
                            fofoOpeningStockRepository.delete(existingStock);
5575
                            LOGGER.info("Deleted record with fofoId: {}, catalogId: {} because averageQty, openingQty, and currentQty meet deletion criteria", fofoId, catalogId);
5576
                        } else {
5577
                            // Update the existing stock with the new average quantity
5578
                            existingStock.setOpeningQty(averageQty);
34244 ranu 5579
                            existingStock.setCurrentQty(partnerCurrentQty);
33878 ranu 5580
                            existingStock.setOpeningDate(LocalDate.now());
34363 ranu 5581
                            LOGGER.info("Updated due to date being older than 5 days with average quantity: {}", averageQty);
33878 ranu 5582
                        }
34275 tejus.loha 5583
                    } else {
34244 ranu 5584
                        existingStock.setCurrentQty(partnerCurrentQty);
33874 ranu 5585
                    }
5586
                } else {
5587
                    LOGGER.info("else condition exist");
5588
                    FofoOpeningStock newStock = new FofoOpeningStock();
5589
                    newStock.setFofoId(fofoId);
5590
                    newStock.setCatalogId(catalogId);
34162 ranu 5591
                    newStock.setOpeningQty(partnerCurrentQty);
5592
                    newStock.setCurrentQty(partnerCurrentQty);
33874 ranu 5593
                    newStock.setOpeningDate(openingDate);
5594
                    fofoOpeningStockRepository.persist(newStock);
5595
 
5596
                }
5597
            }
34162 ranu 5598
 
5599
//            if stock is not available in snapshot but available in opening stock
34275 tejus.loha 5600
            List<FofoOpeningStock> fofoOpeningStockList = fofoOpeningStockRepository.selectAllByFofoId(fofoId);
34162 ranu 5601
 
34275 tejus.loha 5602
            for (FofoOpeningStock fofoOpeningStock : fofoOpeningStockList) {
34162 ranu 5603
 
34275 tejus.loha 5604
                if (!partnerStockList.stream().anyMatch(partnerStock -> partnerStock.getCatalogId() == fofoOpeningStock.getCatalogId())) {
34363 ranu 5605
                    if (fofoOpeningStock.getOpeningDate().isBefore(LocalDate.now().minusDays(5))) {
34275 tejus.loha 5606
                        LOGGER.info("not match stock{}", fofoOpeningStock);
5607
                        fofoOpeningStockRepository.delete(fofoOpeningStock);
5608
                    } else {
5609
                        LOGGER.info("not match stock2{}", fofoOpeningStock);
5610
                        fofoOpeningStock.setCurrentQty(0);
5611
                    }
34162 ranu 5612
 
34275 tejus.loha 5613
                }
5614
            }
34162 ranu 5615
 
33874 ranu 5616
        }
5617
    }
5618
 
5619
 
34162 ranu 5620
    @Autowired
5621
    private CategorisedCatalogRepository categorisedCatalogRepository;
5622
 
5623
    public void groupHidCatalogsByWeeks() throws ProfitMandiBusinessException, MessagingException, IOException {
5624
        List<CategorisedCatalogListModel> categorisedCatalogs = categorisedCatalogRepository.getListByStatus(CatalogMovingEnum.HID);
5625
        LocalDate currentDate = LocalDate.now();
5626
        LocalDate oneWeekAgo = currentDate.minusDays(7);
5627
        LocalDate twoWeeksAgo = currentDate.minusDays(14);
5628
        LocalDate threeWeeksAgo = currentDate.minusDays(21);
5629
 
5630
        // This Week (inclusive of the current date)
5631
        List<CategorisedCatalogListModel> thisWeekCatalogs = categorisedCatalogs.stream()
5632
                .filter(catalog -> !catalog.getStatusCreatedDate().isBefore(oneWeekAgo))
5633
                .collect(Collectors.toList());
5634
 
5635
        // Last Week (from one week ago to two weeks ago, exclusive of this week)
5636
        List<CategorisedCatalogListModel> lastWeekCatalogs = categorisedCatalogs.stream()
5637
                .filter(catalog -> catalog.getStatusCreatedDate().isBefore(oneWeekAgo) && !catalog.getStatusCreatedDate().isBefore(twoWeeksAgo))
5638
                .collect(Collectors.toList());
5639
 
5640
        // Two Weeks Ago (from two weeks ago to three weeks ago, exclusive of last week)
5641
        List<CategorisedCatalogListModel> twoWeeksAgoCatalogs = categorisedCatalogs.stream()
5642
                .filter(catalog -> catalog.getStatusCreatedDate().isBefore(twoWeeksAgo) && !catalog.getStatusCreatedDate().isBefore(threeWeeksAgo))
5643
                .collect(Collectors.toList());
5644
 
5645
        // Older than Two Weeks Ago (anything older than three weeks ago)
5646
        List<CategorisedCatalogListModel> olderCatalogs = categorisedCatalogs.stream()
5647
                .filter(catalog -> catalog.getStatusCreatedDate().isBefore(threeWeeksAgo))
5648
                .collect(Collectors.toList());
5649
 
5650
 
5651
        String subject = "Hid Catalogs";
5652
        StringBuilder sb = new StringBuilder();
5653
 
5654
        sb.append("<html><body><p>Hi Catagory Team,\n");
5655
        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;'>");
5656
 
5657
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
5658
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
5659
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
5660
        sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");
5661
        sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");
5662
        sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");
5663
        sb.append("</tr>\n");
5664
 
5665
        for (CategorisedCatalogListModel catalog : thisWeekCatalogs) {
5666
            sb.append("<tr>");
5667
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");
5668
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");
5669
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");
5670
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");
5671
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");
5672
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");
5673
 
5674
            sb.append("</tr>\n");
5675
 
5676
        }
5677
 
5678
        sb.append("</table>");
5679
 
5680
        sb.append("</br>");
5681
        sb.append("</br>");
5682
        sb.append("</br>");
5683
        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;'>");
5684
 
5685
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
5686
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
5687
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
5688
        sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");
5689
        sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");
5690
        sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");
5691
        sb.append("</tr>\n");
5692
 
5693
        for (CategorisedCatalogListModel catalog : lastWeekCatalogs) {
5694
            sb.append("<tr>");
5695
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");
5696
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");
5697
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");
5698
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");
5699
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");
5700
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");
5701
 
5702
            sb.append("</tr>\n");
5703
 
5704
        }
5705
        sb.append("</table>");
5706
 
5707
        sb.append("</br>");
5708
        sb.append("</br>");
5709
        sb.append("</br>");
5710
        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;'>");
5711
 
5712
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
5713
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
5714
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
5715
        sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");
5716
        sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");
5717
        sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");
5718
        sb.append("</tr>\n");
5719
 
5720
        for (CategorisedCatalogListModel catalog : twoWeeksAgoCatalogs) {
5721
            sb.append("<tr>");
5722
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");
5723
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");
5724
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");
5725
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");
5726
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");
5727
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");
5728
 
5729
            sb.append("</tr>\n");
5730
 
5731
        }
5732
        sb.append("</table>");
5733
 
5734
        sb.append("</br>");
5735
        sb.append("</br>");
5736
        sb.append("</br>");
5737
        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;'>");
5738
 
5739
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
5740
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
5741
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
5742
        sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");
5743
        sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");
5744
        sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");
5745
        sb.append("</tr>\n");
5746
 
5747
        for (CategorisedCatalogListModel catalog : olderCatalogs) {
5748
            sb.append("<tr>");
5749
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");
5750
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");
5751
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");
5752
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");
5753
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");
5754
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");
5755
 
5756
            sb.append("</tr>\n");
5757
 
5758
        }
5759
        sb.append("</table>");
5760
        sb.append("</body></html>");
5761
 
36936 vikas 5762
        List<String> sendTo = Arrays.asList("sourcing@smartdukaan.com", "tarun.verma@smartdukaan.com");
34162 ranu 5763
 
5764
 
5765
        String[] email = sendTo.toArray(new String[sendTo.size()]);
5766
 
36402 amit 5767
        this.sendMailOfHtmlFormat(gmailRelaySender, email, sb.toString(), null, subject);
34162 ranu 5768
    }
5769
 
34275 tejus.loha 5770
    public void send10OrMoreOlderStockReport() throws Exception {
35094 ranu 5771
        System.out.print("testSTart");
34352 amit.gupta 5772
        purSaleService.moreThen10DaysEgedStockReport();
35094 ranu 5773
        System.out.print("testEnd");
34162 ranu 5774
 
34275 tejus.loha 5775
    }
34162 ranu 5776
 
34791 aman.kumar 5777
    public void sendUpdateMobileBrandMarketShareQuaterlyMail() throws Exception {
5778
        String subject = "Reminder: Please Update Brand-wise Market Share";
5779
 
5780
        String body = "Dear Team,\n\n" +
5781
                "This is a gentle reminder to kindly update the brand-wise market share data for the current quarter.\n\n" +
5782
                "Best regards,\n" +
5783
                "SmartDukaan Team";
5784
 
35959 amit 5785
        mailOutboxService.queueMailViaGoogle(
34791 aman.kumar 5786
                new String[]{"sm.@smartdukaan.com"},
5787
                new String[]{"tech@smartdukaan.com"},
5788
                subject,
35959 amit 5789
                body,
5790
                "ScheduledTasks.sendUpdateMobileBrandMarketShareQuaterlyMail"
34791 aman.kumar 5791
        );
5792
    }
5793
 
5794
 
36581 amit 5795
    @Scheduled(fixedRate = 1800000)
5796
    public void refreshSnapshotAgeing() {
5797
        try {
5798
            sessionFactory.getCurrentSession().createNativeQuery(
5799
                    "UPDATE inventory.currentinventorysnapshot cis " +
5800
                    "JOIN ( " +
5801
                    "    SELECT itemId, currentWarehouseId, " +
5802
                    "           MIN(rootInvoiceDate) AS oldest, " +
5803
                    "           MAX(rootInvoiceDate) AS newest " +
5804
                    "    FROM warehouse.inventoryItem " +
5805
                    "    WHERE currentQuantity > 0 AND rootInvoiceDate IS NOT NULL " +
5806
                    "    GROUP BY itemId, currentWarehouseId " +
5807
                    ") agg ON agg.itemId = cis.item_id AND agg.currentWarehouseId = cis.warehouse_id " +
5808
                    "SET cis.oldest_invoice_date = agg.oldest, " +
5809
                    "    cis.newest_invoice_date = agg.newest"
5810
            ).executeUpdate();
5811
            LOGGER.info("Snapshot ageing refreshed");
5812
        } catch (Exception e) {
5813
            LOGGER.error("Error refreshing snapshot ageing", e);
5814
        }
5815
    }
5816
 
32210 jai.hind 5817
}
33664 amit.gupta 5818
// 2284"