Subversion Repositories SmartDukaan

Rev

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