Subversion Repositories SmartDukaan

Rev

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