Subversion Repositories SmartDukaan

Rev

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