Subversion Repositories SmartDukaan

Rev

Rev 37417 | Rev 37472 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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