Subversion Repositories SmartDukaan

Rev

Rev 37470 | Rev 37482 | 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
 
32482 amit.gupta 3742
    public void selectFinServiceFollowUpDateByCurrDate(LocalDate currentDate) throws
3743
            MessagingException, ProfitMandiBusinessException, IOException {
31697 amit.gupta 3744
        LOGGER.info("selectfinServiceFollow - {}", "selectfinServiceFollowUpDateByCurrDate");
29308 tejbeer 3745
 
31697 amit.gupta 3746
        serviceConfigService.selectFinServicePartnerfollowUpDateByCurrentDate(currentDate);
29252 amit.gupta 3747
 
31697 amit.gupta 3748
    }
29451 manish 3749
 
31697 amit.gupta 3750
    public void checkCancellationMargin() throws Exception {
3751
        LocalDateTime startDate = LocalDate.of(2021, 4, 1).atStartOfDay();
3752
        List<FofoOrder> fofoOrders = fofoOrderRepository.selectCancelledBetweenSaleDate(startDate, LocalDateTime.now());
3753
        LOGGER.info("Total Orders =  {}", fofoOrders.size());
3754
        for (FofoOrder fofoOrder : fofoOrders) {
31886 tejbeer 3755
            List<UserWalletHistory> history = userWalletHistoryRepository.selectAllByreferenceIdandreferenceType(fofoOrder.getId(), WalletReferenceType.SCHEME_OUT);
3756
            history.addAll(userWalletHistoryRepository.selectAllByreferenceIdandreferenceType(fofoOrder.getId(), WalletReferenceType.ACTIVATION_SCHEME));
31697 amit.gupta 3757
            int walletSum = history.stream().mapToInt(x -> x.getAmount()).sum();
3758
            if (Math.abs(walletSum) > 1) {
3759
                // LOGGER.info("Cancelled invoice {}, Order Id = {}, = havent rolledback, Value
3760
                // = {}", fofoOrder.getInvoiceNumber(), fofoOrder.getId(), walletSum);
3761
                List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
3762
                List<FofoLineItem> flis = fofoLineItemRepository.selectByFofoOrderItemId(fofoOrderItems.get(0).getId());
3763
                FofoLineItem fli = flis.get(0);
3764
                if (StringUtils.isEmpty(fli.getSerialNumber()))
3765
                    continue;
31886 tejbeer 3766
                List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectByInventoryItemIds(new HashSet<>(Arrays.asList(fli.getInventoryItemId())));
31697 amit.gupta 3767
                InventoryItem inventoryItem = inventoryItemRepository.selectById(fli.getInventoryItemId());
31886 tejbeer 3768
                double schemeSum = schemeInOuts.stream().filter(x -> x.getRolledBackTimestamp() == null).mapToDouble(x -> x.getAmount()).sum();
31697 amit.gupta 3769
                /*
3770
                 * if(inventoryItem.getGoodQuantity()==1) {
3771
                 * LOGGER.info("GoodQty, Serial Number {}, InventoryItem = {}, Billed on {}",
3772
                 * inventoryItem.getSerialNumber(), inventoryItem.getId(),
3773
                 * inventoryItem.getUpdateTimestamp()); } else
3774
                 * if(inventoryItem.getBadQuantity()==1){
3775
                 * LOGGER.info("Bad Qty, Serial Number {}, InventoryItem = {}, Billed on {}",
3776
                 * inventoryItem.getSerialNumber(), inventoryItem.getId(),
3777
                 * inventoryItem.getUpdateTimestamp()); } else if
3778
                 * (inventoryItem.getLastScanType().equals(ScanType.SALE)) { LOGGER.
3779
                 * info("Problem Sold, Serial Number {}, InventoryItem = {}, Billed on {}",
3780
                 * inventoryItem.getSerialNumber(), inventoryItem.getId(),
3781
                 * inventoryItem.getUpdateTimestamp()); }
3782
                 */
31886 tejbeer 3783
                if (inventoryItem.getLastScanType().equals(ScanType.SALE) || inventoryItem.getLastScanType().equals(ScanType.SALE_RET)) {
3784
                    Map<String, Double> map = schemeInOuts.stream().collect(
3785
                            groupingBy(
3786
                                    x -> DateTimeFormatter.ofPattern("yyyyMMddHH").format(x.getCreateTimestamp()) + "- " + x.getSchemeId(), Collectors.summingDouble(x -> x.getAmount())));
33452 amit.gupta 3787
                    for (Entry<String, Double> entry : map.entrySet()) {
31697 amit.gupta 3788
                        LOGGER.info("{} = {}", entry.getKey(), entry.getValue());
3789
                    }
31886 tejbeer 3790
                    LOGGER.info("id- {}, imei- {}, lastScan = {}, Scheme sum - {}", inventoryItem.getId(), inventoryItem.getSerialNumber(), inventoryItem.getLastScanType(), schemeSum);
31697 amit.gupta 3791
                }
3792
            }
3793
        }
29441 tejbeer 3794
 
31697 amit.gupta 3795
    }
29308 tejbeer 3796
 
31697 amit.gupta 3797
    public static String readFileAsString(String file) throws Exception {
3798
        String data = "";
3799
        data = new String(Files.readAllBytes(Paths.get(file)));
3800
        return data;
3801
    }
29308 tejbeer 3802
 
31697 amit.gupta 3803
    @Autowired
3804
    private PartnerCollectionRemarkRepository partnerCollectionRemarkRepository;
30421 tejbeer 3805
 
32832 amit.gupta 3806
    //RBM L2 Escalations
32482 amit.gupta 3807
    public void reviewUncontactablePartner() throws
3808
            ProfitMandiBusinessException, MessagingException, UnsupportedEncodingException {
30421 tejbeer 3809
 
31697 amit.gupta 3810
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(true);
30421 tejbeer 3811
 
32832 amit.gupta 3812
        List<Integer> partnerLastCollectionRemarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(new ArrayList<>(customRetailerMap.keySet()));
30859 tejbeer 3813
 
32832 amit.gupta 3814
        if (!partnerLastCollectionRemarkIds.isEmpty()) {
3815
            List<PartnerCollectionRemark> partnerCollectionRemarks = partnerCollectionRemarkRepository.selectByIds(partnerLastCollectionRemarkIds);
30421 tejbeer 3816
 
33064 ranu 3817
            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 3818
            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 3819
            Map<Integer, PartnerCollectionRemark> salesEscalatedRemarksMap = partnerCollectionRemarks.stream().filter(x -> x.getRemark().equals(CollectionRemark.SALES_ESCALATION)).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
30859 tejbeer 3820
 
32832 amit.gupta 3821
 
3822
            if (!rbmEscalatedRemarksMap.isEmpty()) {
3823
                //
33452 amit.gupta 3824
                for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_RBM), true).entrySet()) {
32832 amit.gupta 3825
                    List<PartnerCollectionRemark> filteredRows = storeGuyEntry.getValue().stream()
3826
                            .map(x -> rbmEscalatedRemarksMap.get(x)).filter(x -> x != null).collect(Collectors.toList());
3827
                    String subject = "Partners escalated to RBM-L2";
3828
                    String messageText = this.getMessageForRBMEscalatedPartners(filteredRows);
3829
 
36402 amit 3830
                    MimeMessage message = gmailRelaySender.createMimeMessage();
31697 amit.gupta 3831
                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
3832
                    String[] email = new String[]{storeGuyEntry.getKey()};
30859 tejbeer 3833
 
31697 amit.gupta 3834
                    helper.setSubject(subject);
3835
                    helper.setText(messageText, true);
3836
                    helper.setTo(email);
31886 tejbeer 3837
                    InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");
31697 amit.gupta 3838
                    helper.setFrom(senderAddress);
36402 amit 3839
                    gmailRelaySender.send(message);
30859 tejbeer 3840
 
36269 ranu 3841
                }
3842
            }
3843
            if (!rbmL3EscalatedRemarksMap.isEmpty()) {
3844
                //
3845
                for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_RBM), true).entrySet()) {
3846
                    List<PartnerCollectionRemark> filteredRows = storeGuyEntry.getValue().stream()
3847
                            .map(x -> rbmL3EscalatedRemarksMap.get(x)).filter(x -> x != null).collect(Collectors.toList());
3848
                    String subject = "Partners escalated to RBM-L3";
3849
                    String messageText = this.getMessageForRBMEscalatedPartners(filteredRows);
30859 tejbeer 3850
 
36402 amit 3851
                    MimeMessage message = gmailRelaySender.createMimeMessage();
36269 ranu 3852
                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
3853
                    String[] email = new String[]{storeGuyEntry.getKey()};
3854
 
3855
                    helper.setSubject(subject);
3856
                    helper.setText(messageText, true);
3857
                    helper.setTo(email);
3858
                    InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");
3859
                    helper.setFrom(senderAddress);
36402 amit 3860
                    gmailRelaySender.send(message);
36269 ranu 3861
 
31697 amit.gupta 3862
                }
3863
            }
32832 amit.gupta 3864
            if (!salesEscalatedRemarksMap.isEmpty()) {
3865
                //
35521 amit 3866
                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 3867
                    List<PartnerCollectionRemark> filteredRows = storeGuyEntry.getValue().stream()
3868
                            .map(x -> salesEscalatedRemarksMap.get(x)).filter(x -> x != null).collect(Collectors.toList());
3869
                    String subject = "Partners escalated to Sales";
3870
                    String messageText = this.getMessageForSalesEscalatedPartners(filteredRows);
30936 tejbeer 3871
 
36402 amit 3872
                    MimeMessage message = gmailRelaySender.createMimeMessage();
32832 amit.gupta 3873
                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
3874
                    String[] email = new String[]{storeGuyEntry.getKey()};
3875
 
3876
                    helper.setSubject(subject);
3877
                    helper.setText(messageText, true);
3878
                    helper.setTo(email);
3879
                    InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");
3880
                    helper.setFrom(senderAddress);
36402 amit 3881
                    gmailRelaySender.send(message);
32832 amit.gupta 3882
 
3883
                }
3884
            }
3885
 
31697 amit.gupta 3886
        }
3887
    }
30936 tejbeer 3888
 
33078 ranu 3889
 
31697 amit.gupta 3890
    @Autowired
33078 ranu 3891
    private NonSdBuyingRepository nonSdBuyingRepository;
3892
 
3893
    //Non Sd Buying
3894
    public void reviewNonSdBuyingBrand() throws
3895
            ProfitMandiBusinessException, MessagingException, UnsupportedEncodingException {
3896
        List<NonSdBuying> nonSdByuingActiveList = nonSdBuyingRepository.selectAllActiveNonSDBuyingList(true);
3897
        Map<Integer, NonSdBuying> unAuthorizedBuyingMap = nonSdByuingActiveList.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
3898
 
3899
        if (!unAuthorizedBuyingMap.isEmpty()) {
35521 amit 3900
            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 3901
                List<NonSdBuying> unAuthorizedfilteredRows = storeGuyEntry.getValue().stream()
3902
                        .map(x -> unAuthorizedBuyingMap.get(x)).filter(x -> x != null).collect(Collectors.toList());
33112 amit.gupta 3903
                if (!unAuthorizedfilteredRows.isEmpty()) {
33078 ranu 3904
                    String subject = "Unauthorized Buying";
3905
                    String messageText = this.getMessageForUnauthorizedBuying(unAuthorizedfilteredRows);
3906
 
36402 amit 3907
                    MimeMessage message = gmailRelaySender.createMimeMessage();
33078 ranu 3908
                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
3909
                    String[] email = new String[]{storeGuyEntry.getKey()};
3910
 
3911
                    helper.setSubject(subject);
3912
                    helper.setText(messageText, true);
3913
                    helper.setTo(email);
3914
                    InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");
3915
                    helper.setFrom(senderAddress);
36402 amit 3916
                    gmailRelaySender.send(message);
33078 ranu 3917
                    LOGGER.info("unAuthorizedfilteredRows {}", unAuthorizedfilteredRows);
3918
                }
3919
 
3920
 
3921
            }
3922
 
3923
        }
3924
    }
3925
 
3926
    @Autowired
31697 amit.gupta 3927
    private LoanRepository loanRepository;
31020 tejbeer 3928
 
31697 amit.gupta 3929
    @Autowired
3930
    private LoanStatementRepository loanStatementRepository;
30859 tejbeer 3931
 
31697 amit.gupta 3932
    @Autowired
3933
    private SDCreditRequirementRepository sdCreditRequirementRepository;
30859 tejbeer 3934
 
31697 amit.gupta 3935
    @Autowired
3936
    private CurrentPartnerDailyInvestmentRepository currentPartnerDailyInvestmentRepository;
30859 tejbeer 3937
 
31697 amit.gupta 3938
    @Autowired
3939
    private TransactionRepository transactionRepository;
30859 tejbeer 3940
 
31697 amit.gupta 3941
    @Autowired
3942
    private SanctionRequestRepository sanctionRequestRepository;
30859 tejbeer 3943
 
31697 amit.gupta 3944
    public void calculateInterestAccured() throws ProfitMandiBusinessException {
36289 amit 3945
        synchronized (SD_CREDIT_LOCK) {
3946
            List<Loan> loans = loanRepository.selectAllActiveLoan();
30859 tejbeer 3947
 
36289 amit 3948
            for (Loan loan : loans) {
3949
                List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(loan.getId());
3950
                Map<LoanReferenceType, Double> loanStatusAmount = loanStatements.stream().collect(groupingBy(
3951
                        x -> x.getLoanReferenceType(), Collectors.summingDouble(x -> x.getAmount().doubleValue())));
30936 tejbeer 3952
 
36289 amit 3953
                // Interest starts from this date (inclusive). Under current policy (MIN_FREE_DAYS=1),
3954
                // this is at minimum createdOn + 1 — billing day is always free.
3955
                LocalDate interestStartDate = com.spice.profitmandi.service.transaction.SDCreditServiceImpl.computeInterestStartDate(loan);
30936 tejbeer 3956
 
36289 amit 3957
                LOGGER.info("Loan id - {}, interestStartDate {}", loan.getId(), interestStartDate);
3958
                if (!LocalDate.now().isBefore(interestStartDate)) {
3959
                    int loanStatementId = loanStatementRepository.selectLatestLoanSatement(loan.getFofoId(), loan.getId());
3960
                    LOGGER.info("loanStatementId {}", loanStatementId);
3961
                    if (loanStatementId != 0) {
3962
                        this.calculateInterest(loan, loanStatusAmount, loanStatementId);
3963
                    } else {
3964
                        sdCreditService.addInterest(interestStartDate, LocalDate.now(), loan, loanStatusAmount);
3965
                    }
31697 amit.gupta 3966
                }
32724 amit.gupta 3967
            }
31697 amit.gupta 3968
        }
3969
    }
30936 tejbeer 3970
 
31697 amit.gupta 3971
    @Autowired
3972
    FofoPaymentRepository fofoPaymentRepository;
30936 tejbeer 3973
 
31697 amit.gupta 3974
    @Autowired
3975
    CCAvenuePaymentService ccAvenuePaymentService;
30936 tejbeer 3976
 
31697 amit.gupta 3977
    public void settleCCAvePayments() throws Exception {
31886 tejbeer 3978
        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 3979
        for (FofoPayment fofoPayment : fofoPayments) {
3980
            ccAvenuePaymentService.updatePayment(fofoPayment);
3981
        }
3982
    }
30859 tejbeer 3983
 
31697 amit.gupta 3984
    /*
3985
     * public void getCCAvenuePendingOrderStatus(int pendingOrderId) { PendingOrder
3986
     * pendingOrder = pendingOrderRepository.selectById(pendingOrderId);
3987
     * ccAvenuePaymentService.getPaymentStatusMap(pendingOrder); }
3988
     */
30859 tejbeer 3989
 
32482 amit.gupta 3990
    private void calculateInterest(Loan loan, Map<LoanReferenceType, Double> loanStatusAmount,
3991
                                   int loanStatementId) throws ProfitMandiBusinessException {
31697 amit.gupta 3992
        LoanStatement loanStatement = loanStatementRepository.selectById(loanStatementId);
30859 tejbeer 3993
 
31697 amit.gupta 3994
        if (loanStatement.getLoanId() == loan.getId()) {
34710 amit.gupta 3995
            sdCreditService.addInterest(loanStatement.getCreatedAt().toLocalDate().plusDays(1), LocalDate.now(), loan, loanStatusAmount);
31697 amit.gupta 3996
        } else {
3997
            throw new ProfitMandiBusinessException("loanstament", loanStatement.getLoanId(), "Invalid LoanId");
3998
        }
3999
    }
31175 tejbeer 4000
 
31697 amit.gupta 4001
    public void loanSettlement() throws Exception {
36289 amit 4002
        synchronized (SD_CREDIT_LOCK) {
4003
            List<Loan> loans = loanRepository.selectAllActiveLoanForSettlement().stream().filter(x -> x.canBeSettled()).collect(toList());
4004
            //TODO:Upto here
4005
            if (!loans.isEmpty()) {
31020 tejbeer 4006
 
36289 amit 4007
                for (Loan loan : loans) {
4008
                    LOGGER.info("Loan - {},  {}", loan.getId(), loan.canBeSettled());
4009
                    double settledAmount = sdCreditService.settleLoan(loan);
30859 tejbeer 4010
 
36289 amit 4011
                    List<SanctionRequest> sanctionRequests = sanctionRequestRepository.selectHoldSanctionByFofoId(loan.getFofoId());
4012
                    for (SanctionRequest sanctionRequest : sanctionRequests) {
31175 tejbeer 4013
 
36289 amit 4014
                        List<Order> orders = orderRepository.selectAllByTransactionId(sanctionRequest.getTransactionId());
4015
                        if (orders.size() == 0) {
4016
                            LOGGER.info("Could not find orders - for Sanction Request {}", sanctionRequest);
4017
                            continue;
4018
                        }
30999 tejbeer 4019
 
36289 amit 4020
                        if (settledAmount >= sanctionRequest.getPendingAmount().doubleValue()) {
4021
                            settledAmount -= sanctionRequest.getPendingAmount().doubleValue();
4022
                            sanctionRequest.setPendingAmount(BigDecimal.valueOf(0));
4023
                            this.sendUnholdEmail(orders);
4024
                        } else {
4025
                            double pendinAmount = sanctionRequest.getPendingAmount().doubleValue() - settledAmount;
4026
                            System.out.println("Pending Amount - " + pendinAmount);
4027
                            sanctionRequest.setPendingAmount(BigDecimal.valueOf(pendinAmount));
4028
                            break;
33828 ranu 4029
 
36289 amit 4030
                        }
4031
 
34275 tejus.loha 4032
                    }
36289 amit 4033
                }
34162 ranu 4034
 
32439 tejbeer 4035
            }
34275 tejus.loha 4036
        }
33664 amit.gupta 4037
 
32439 tejbeer 4038
    }
31020 tejbeer 4039
 
4040
 
32439 tejbeer 4041
    private void sendUnholdEmail(List<Order> orders) throws Exception {
30859 tejbeer 4042
 
4043
 
32439 tejbeer 4044
        orders.forEach(x -> x.setShipmentHold(false));
33452 amit.gupta 4045
        orders = orders.stream().filter(x -> x.getRefundTimestamp() != null).collect(Collectors.toList());
33506 amit.gupta 4046
        if (orders.size() > 0) {
33427 amit.gupta 4047
 
33664 amit.gupta 4048
            double totalAmount = orders.stream().collect(Collectors.summingDouble(x -> x.getTotalAmount()));
30859 tejbeer 4049
 
33506 amit.gupta 4050
            List<String> authUserEmail = csService.getAuthUserIdByPartnerId(orders.get(0).getRetailerId()).stream().map(x -> x.getEmailId()).collect(Collectors.toList());
4051
            authUserEmail.add("vinay.p@smartdukaan.com");
4052
            authUserEmail.add("shivam.gupta@smartdukaan.com");
30859 tejbeer 4053
 
33506 amit.gupta 4054
            String[] emailTo = authUserEmail.toArray(new String[authUserEmail.size()]);
30859 tejbeer 4055
 
33506 amit.gupta 4056
            String[] ccTo = {"tarun.verma@smartdukaan.com", "kamini.sharma@smartdukaan.com"};
30859 tejbeer 4057
 
33664 amit.gupta 4058
            String subject = "Dispatch held orders of - " + (orders.get(0).getRetailerName());
4059
            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 4060
            mailOutboxService.queueMailViaGoogle(emailTo, ccTo, subject, message, "ScheduledTasks.sendUnholdEmail");
33506 amit.gupta 4061
        }
30859 tejbeer 4062
 
32439 tejbeer 4063
 
31697 amit.gupta 4064
    }
30859 tejbeer 4065
 
36745 ranu 4066
    // Nightly at 23:30: detect beat-days the assignee missed (no PUNCHIN, or punched
4067
    // in but no stops worked) and fan out per-stop miss rows into beat_deferred_visit
4068
    // so the Deferred Partners panel surfaces them. Idempotent on repeat runs.
4069
    @Scheduled(cron = "0 30 23 * * *")
4070
    public void detectMissedBeats() {
4071
        try {
4072
            beatMissDetectorRunner.syncMissesForDate(java.time.LocalDate.now());
4073
        } catch (Exception e) {
4074
            LOGGER.error("detectMissedBeats failed", e);
4075
        }
4076
    }
4077
 
37417 vikas 4078
    // Every 30 min: score today's freshly checked-out partner-visit remarks so the
4079
    // Beat Journey remark-quality flags (#2/#10/#12) stay current. Idempotent — each
4080
    // remark is scored (committed) exactly once; a re-run scores 0 rows.
4081
    @Scheduled(fixedRate = 1800000)
4082
    public void scoreVisitRemarks() {
4083
        try {
4084
            remarkScoreRunner.scoreForDate(java.time.LocalDate.now());
4085
        } catch (Exception e) {
4086
            LOGGER.error("scoreVisitRemarks failed", e);
4087
        }
4088
    }
4089
 
4090
    // 09:15 daily: consolidated HR mail of employees who reused one remark across
4091
    // agendas on more than 3 visits this month (month-to-date, so an offender stays
4092
    // listed for the rest of the month). Silent on a day when nobody is over the line.
4093
    @Scheduled(cron = "0 15 9 * * *")
4094
    public void duplicateRemarkDigest() {
4095
        try {
4096
            duplicateRemarkDigestRunner.sendDigestForDate(java.time.LocalDate.now());
4097
        } catch (Exception e) {
4098
            LOGGER.error("duplicateRemarkDigest failed", e);
4099
        }
4100
    }
4101
 
37172 amit 4102
    // Nightly PJP agenda sync: evaluate the 5 AUTO agenda rules per partner and
4103
    // open/close user.agenda_instance rows. Scheduled from ScheduledSkeleton at
4104
    // 23:45 — after the 23:30 activation-type cron, so the REVIVAL mirror sees
4105
    // today's state.
4106
    public void updatePjpAgendaInstances() {
4107
        AgendaSyncResult result = agendaAutoRuleService.syncAllPartners();
4108
        LOGGER.info("updatePjpAgendaInstances: {}", result);
4109
        if (result.getErrors() > 0) {
4110
            String body = "PJP agenda sync finished with errors.\n\n" + result + "\n\n"
4111
                    + String.join("\n", result.getErrorDetails());
4112
            mailOutboxService.queueMailViaGoogle(
4113
                    "amit.gupta@smartdukaan.com",
37173 amit 4114
                    new String[]{},
37172 amit 4115
                    "PJP agenda sync: " + result.getErrors() + " errors",
4116
                    body,
4117
                    "ScheduledTasks.updatePjpAgendaInstances");
4118
        }
4119
    }
4120
 
36561 amit 4121
    @Scheduled(cron = "0 0 1 * * *")
36556 amit 4122
    public void convertExpiredFlagshipCredits() {
4123
        synchronized (SD_CREDIT_LOCK) {
4124
            try {
4125
                sdCreditService.convertExpiredFlagshipCredits();
4126
            } catch (Exception e) {
4127
                LOGGER.error("Error converting expired flagship credits", e);
4128
            }
4129
        }
4130
    }
4131
 
36561 amit 4132
    public void testFlagshipBilling(int transactionId, double invoiceAmount, String invoiceNumber) {
4133
        synchronized (SD_CREDIT_LOCK) {
4134
            try {
4135
                System.out.println("=== TEST: Calling createLoanForBilling ===");
4136
                System.out.println("transactionId=" + transactionId + ", invoiceAmount=" + invoiceAmount + ", invoiceNumber=" + invoiceNumber);
4137
                sdCreditService.createLoanForBilling(transactionId, invoiceAmount, invoiceNumber);
4138
                System.out.println("=== TEST: createLoanForBilling completed ===");
4139
            } catch (Exception e) {
4140
                System.out.println("=== TEST: ERROR ===");
4141
                e.printStackTrace();
4142
            }
4143
        }
4144
    }
4145
 
36556 amit 4146
    public void notifyFlagshipExpiryIn2Days() {
4147
        try {
4148
            java.time.LocalDate expiryDate = java.time.LocalDate.now().plusDays(2);
4149
            List<Loan> expiringLoans = loanRepository.selectFlagshipLoansExpiringOn(expiryDate);
4150
            LOGGER.info("Found {} flagship credits expiring on {}", expiringLoans.size(), expiryDate);
4151
 
4152
            Map<Integer, List<Loan>> byPartner = expiringLoans.stream()
4153
                    .collect(java.util.stream.Collectors.groupingBy(Loan::getFofoId));
4154
 
4155
            for (Map.Entry<Integer, List<Loan>> entry : byPartner.entrySet()) {
4156
                int fofoId = entry.getKey();
4157
                List<Loan> loans = entry.getValue();
4158
                double totalAmount = loans.stream().mapToDouble(l -> l.getPendingAmount().doubleValue()).sum();
4159
 
4160
                String title = "Flagship Credit Expiring Soon";
4161
                String message = String.format(
4162
                        "Your flagship credit of Rs.%.0f will convert to a regular loan on %s. " +
4163
                        "Sell the items before then to avoid interest charges.",
4164
                        totalAmount, expiryDate.format(java.time.format.DateTimeFormatter.ofPattern("dd-MMM-yyyy")));
4165
 
4166
                try {
4167
                    int userId = userAccountRepository.selectUserIdByRetailerId(fofoId);
4168
                    SendNotificationModel model = new SendNotificationModel();
4169
                    model.setCampaignName("Flagship credit expiry reminder");
4170
                    model.setTitle(title);
4171
                    model.setMessage(message);
4172
                    model.setType("url");
4173
                    model.setUrl("https://app.smartdukaan.com/pages/home/credit");
4174
                    model.setExpiresat(java.time.LocalDateTime.now().plusDays(2));
4175
                    model.setMessageType(MessageType.reminder);
4176
                    model.setUserIds(java.util.Arrays.asList(userId));
4177
                    notificationService.sendNotification(model);
4178
                } catch (Exception e) {
4179
                    LOGGER.error("Failed to send flagship expiry notification to fofoId {}", fofoId, e);
4180
                }
4181
            }
4182
        } catch (Exception e) {
4183
            LOGGER.error("Error sending flagship expiry notifications", e);
4184
        }
4185
    }
4186
 
32307 amit.gupta 4187
    public void dailyLoanAlert() throws Exception {
31697 amit.gupta 4188
        List<Loan> loans = loanRepository.selectAllActiveLoan();
30859 tejbeer 4189
 
31697 amit.gupta 4190
        Map<Integer, Double> partnerLoanAmount = new HashMap<>();
30859 tejbeer 4191
 
35877 amit 4192
        for (Loan loan : loans) {
4193
            double amount = partnerLoanAmount.getOrDefault(loan.getFofoId(), 0.0);
4194
            amount += loan.getPendingAmount().doubleValue() + loan.getInterestAccrued().doubleValue() - loan.getInterestPaid().doubleValue();
4195
            partnerLoanAmount.put(loan.getFofoId(), amount);
31697 amit.gupta 4196
        }
30859 tejbeer 4197
 
31697 amit.gupta 4198
        if (!partnerLoanAmount.isEmpty()) {
30965 tejbeer 4199
 
31697 amit.gupta 4200
            for (Entry<Integer, Double> partnerLoanAmountEnrty : partnerLoanAmount.entrySet()) {
30859 tejbeer 4201
 
31697 amit.gupta 4202
                int fofoId = partnerLoanAmountEnrty.getKey();
30859 tejbeer 4203
 
31697 amit.gupta 4204
                com.spice.profitmandi.dao.entity.user.User user = userUserRepository.selectById(fofoId);
30859 tejbeer 4205
 
31697 amit.gupta 4206
                Address address = addressRepository.selectById(user.getAddressId());
30896 amit.gupta 4207
 
31697 amit.gupta 4208
                String title = "Alert Credit Outstanding!";
4209
                String url = "http://app.smartdukaan.com/pages/home/credit";
34729 amit.gupta 4210
                String message = "Your total outstanding Credit Balance is Rs." + FormattingUtils.formatDecimal(Math.abs(partnerLoanAmountEnrty.getValue())) + ".";
31697 amit.gupta 4211
                notificationService.sendNotification(fofoId, title, MessageType.notification, title, message, url);
30913 tejbeer 4212
 
32841 amit.gupta 4213
                //notificationService.sendWhatsappMessage(message, title, address.getPhoneNumber());
30913 tejbeer 4214
 
31697 amit.gupta 4215
            }
30917 tejbeer 4216
 
31697 amit.gupta 4217
        }
30917 tejbeer 4218
 
31697 amit.gupta 4219
    }
30920 tejbeer 4220
 
31697 amit.gupta 4221
    public void processActivatedImeisForSchemes() throws ProfitMandiBusinessException {
4222
        schemeService.processActivatedImeisForSchemes();
4223
    }
30920 tejbeer 4224
 
33112 amit.gupta 4225
    @Autowired
33355 amit.gupta 4226
    SidbiService sidbiService;
33112 amit.gupta 4227
 
33364 amit.gupta 4228
    public void processSidbiDeductions() throws ProfitMandiBusinessException {
33434 amit.gupta 4229
        //sidbiService.migrateSanctions();
33355 amit.gupta 4230
        sidbiService.processDeductions();
4231
    }
35521 amit 4232
 
35299 amit 4233
    /*private static List<Integer> hundredPercentLimitPartnerIds = Arrays.asList(175139630,
34510 amit.gupta 4234
            175139815,
4235
            175139844,
4236
            175140101
35299 amit 4237
    );*/
34510 amit.gupta 4238
 
35299 amit 4239
    private static List<Integer> hundredPercentLimitPartnerIds = Arrays.asList();
4240
 
33112 amit.gupta 4241
 
34993 ranu 4242
 
31697 amit.gupta 4243
    public void notifyDefaultLoans() throws ProfitMandiBusinessException, MessagingException, IOException {
36462 ranu 4244
        synchronized (SD_CREDIT_LOCK) {
36289 amit 4245
            sdCreditService.updateRisk();
4246
            List<Loan> defaultLoans = sdCreditService.getDefaultLoans();
4247
            if (!defaultLoans.isEmpty()) {
4248
                this.sendDefaultLoanAlert(defaultLoans);
4249
            }
36462 ranu 4250
        }
31697 amit.gupta 4251
    }
30929 tejbeer 4252
 
32482 amit.gupta 4253
    public void sendDefaultLoanAlert(List<Loan> defaultLoans) throws
4254
            ProfitMandiBusinessException, MessagingException, IOException {
31697 amit.gupta 4255
        String subject = "Default Partners";
30931 tejbeer 4256
 
35591 aman 4257
        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 4258
 
33452 amit.gupta 4259
        for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false).entrySet()) {
31697 amit.gupta 4260
            List<Loan> filteredRows = new ArrayList<>();
4261
            for (Loan loan : defaultLoans) {
30929 tejbeer 4262
 
31697 amit.gupta 4263
                if (storeGuyEntry.getValue().contains(loan.getFofoId())) {
30929 tejbeer 4264
 
31697 amit.gupta 4265
                    filteredRows.add(loan);
4266
                }
4267
            }
4268
            if (!filteredRows.isEmpty()) {
35591 aman 4269
                String[] email = new String[]{storeGuyEntry.getKey(),"neeraj.gupta@smartdukaan.com"};
31697 amit.gupta 4270
                String messageText = this.getMessageForDueDateExtend(filteredRows);
36473 amit 4271
                this.sendMailOfHtmlFormat(googleMailSender, email, messageText, null, subject);
30982 tejbeer 4272
 
31697 amit.gupta 4273
            }
30936 tejbeer 4274
 
31697 amit.gupta 4275
        }
33628 tejus.loha 4276
        String messageText = this.getMessageForDueDateExtend(defaultLoans);
36473 amit 4277
        this.sendMailOfHtmlFormat(googleMailSender, new String[]{"puneet.wahi@smartdukaan.com", "rahul.latwal@smartdukaan.com", "dilbag.singh@smartdukaan.com"}, messageText, null, subject);
30982 tejbeer 4278
 
31697 amit.gupta 4279
        for (Loan defaultLoan : defaultLoans) {
35877 amit 4280
            double principal = defaultLoan.getPendingAmount().doubleValue();
4281
            double interest = defaultLoan.getInterestAccrued().doubleValue() - defaultLoan.getInterestPaid().doubleValue();
4282
            double total = principal + interest;
30929 tejbeer 4283
 
35877 amit 4284
            String title = "Credit Default Alert!";
31697 amit.gupta 4285
            String url = "http://app.smartdukaan.com/pages/home/credit";
35915 amit 4286
            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 4287
            notificationService.sendNotification(defaultLoan.getFofoId(), title, MessageType.notification, title, message, url);
30936 tejbeer 4288
 
31697 amit.gupta 4289
        }
4290
    }
30929 tejbeer 4291
 
31697 amit.gupta 4292
    private String getMessageForDueDateExtend(List<Loan> loans) throws ProfitMandiBusinessException {
33553 ranu 4293
        Map<Integer, com.spice.profitmandi.dao.model.FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();
4294
        Map<Integer, FofoRBMReportingModel> fofoRbmReportingModelMap = csService.getPartnerIdRBMHeaders();
4295
        List<AST> asts = astRepository.selectAll();
4296
        Map<Integer, AST> astMap = asts.stream()
4297
                .collect(Collectors.toMap(AST::getId, ast -> ast));
31697 amit.gupta 4298
        StringBuilder sb = new StringBuilder();
4299
        sb.append(
35877 amit 4300
                "<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 4301
                        "<table style='border:1px solid black ;padding: 5px';>");
4302
        sb.append("<tbody>\n" +
4303
                "<tr>\n" +
4304
                "<th style='border:1px solid black;padding: 5px'>PartnerName</th>\n" +
33555 ranu 4305
                "<th style='border:1px solid black;padding: 5px'>State Name</th>\n" +
4306
                "<th style='border:1px solid black;padding: 5px'>Area</th>\n" +
4307
                "<th style='border:1px solid black;padding: 5px'>Territory</th>\n" +
33553 ranu 4308
                "<th style='border:1px solid black;padding: 5px'>due date</th>\n" +
4309
                "<th style='border:1px solid black;padding: 5px'>Days</th>\n" +
33664 amit.gupta 4310
                "<th style='border:1px solid black;padding: 5px'>Pending Amount</th>\n" +
33810 ranu 4311
                "<th style='border:1px solid black;padding: 5px'>RBM L2</th>\n" +
33553 ranu 4312
                "<th style='border:1px solid black;padding: 5px'>RBM L1</th>\n" +
37351 ranu 4313
                "<th style='border:1px solid black;padding: 5px'>Sales L1/L2</th>\n" +
4314
                "<th style='border:1px solid black;padding: 5px'>Sales L4</th>\n" +
33553 ranu 4315
                "</tr>");
35877 amit 4316
        DecimalFormat df = new DecimalFormat("#.##");
31697 amit.gupta 4317
        for (Loan entry : loans) {
30929 tejbeer 4318
 
35877 amit 4319
            double amount = entry.getPendingAmount().doubleValue() + entry.getInterestAccrued().doubleValue() - entry.getInterestPaid().doubleValue();
30929 tejbeer 4320
 
31697 amit.gupta 4321
            long noOfdaysBetween = ChronoUnit.DAYS.between(entry.getDueDate().toLocalDate(), LocalDateTime.now());
30929 tejbeer 4322
 
31697 amit.gupta 4323
            CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());
30929 tejbeer 4324
 
31697 amit.gupta 4325
            sb.append("<tr>");
31886 tejbeer 4326
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")" + "</td>");
33555 ranu 4327
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getAddress().getState() + "</td>");
4328
            sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getArea() + "</td>");
4329
            sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getTerritory() + "</td>");
31886 tejbeer 4330
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getDueDate().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");
31697 amit.gupta 4331
            sb.append("<td style='border:1px solid black;padding: 5px'>" + noOfdaysBetween + "</td>");
35877 amit 4332
            sb.append("<td style='border:1px solid black;padding: 5px'>" + df.format(amount) + "</td>");
33553 ranu 4333
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL1Manager() + "</td>");
4334
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL2Manager() + "</td>");
37351 ranu 4335
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getTerritoryManager() + "/" + fofoReportingModelMap.get(entry.getFofoId()).getSalesL2Manager() + "</td>");
33553 ranu 4336
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getRegionalManager() + "</td>");
31397 tejbeer 4337
 
31697 amit.gupta 4338
            sb.append("</tr>");
31397 tejbeer 4339
 
31697 amit.gupta 4340
        }
31397 tejbeer 4341
 
31697 amit.gupta 4342
        sb.append("</tbody></table></body></html>");
31397 tejbeer 4343
 
31697 amit.gupta 4344
        return sb.toString();
4345
    }
31397 tejbeer 4346
 
35111 ranu 4347
    private String getMessageForDueDateCross(List<Loan> dueDateCrossLoans) throws ProfitMandiBusinessException {
33161 ranu 4348
        Map<Integer, com.spice.profitmandi.dao.model.FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();
33452 amit.gupta 4349
        Map<Integer, FofoRBMReportingModel> fofoRbmReportingModelMap = csService.getPartnerIdRBMHeaders();
33553 ranu 4350
        List<AST> asts = astRepository.selectAll();
4351
        Map<Integer, AST> astMap = asts.stream()
4352
                .collect(Collectors.toMap(AST::getId, ast -> ast));
4353
 
31697 amit.gupta 4354
        StringBuilder sb = new StringBuilder();
35877 amit 4355
        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 4356
                "<table style='border:1px solid black ;padding: 5px';>");
4357
        sb.append("<tbody>\n" + "<tr>\n" +
33256 amit.gupta 4358
                "<th style='border:1px solid black;padding: 5px'>PartnerName</th>\n" +
36303 aman 4359
                "<th style='border:1px solid black;padding: 5px'>Code</th>\n" +
33256 amit.gupta 4360
                "<th style='border:1px solid black;padding: 5px'>State Name</th>\n" +
33555 ranu 4361
                "<th style='border:1px solid black;padding: 5px'>Area</th>\n" +
33553 ranu 4362
                "<th style='border:1px solid black;padding: 5px'>Territory</th>\n" +
33256 amit.gupta 4363
                "<th style='border:1px solid black;padding: 5px'>due date</th>\n" +
4364
                "<th style='border:1px solid black;padding: 5px'>Days</th>\n" +
4365
                "<th style='border:1px solid black;padding: 5px'>Pending Amount</th>\n" +
33810 ranu 4366
                "<th style='border:1px solid black;padding: 5px'>RBM L2</th>\n" +
33256 amit.gupta 4367
                "<th style='border:1px solid black;padding: 5px'>RBM L1</th>\n" +
4368
                "<th style='border:1px solid black;padding: 5px'>Sales L1</th>\n" +
4369
                "<th style='border:1px solid black;padding: 5px'>Sales L2</th>\n" +
35107 ranu 4370
                "<th style='border:1px solid black;padding: 5px'>Limit Assigned</th>\n" +
33161 ranu 4371
                "</tr>");
31397 tejbeer 4372
 
35877 amit 4373
        DecimalFormat df = new DecimalFormat("#.##");
35111 ranu 4374
        for (Loan entry : dueDateCrossLoans) {
31397 tejbeer 4375
 
35877 amit 4376
            double amount = entry.getPendingAmount().doubleValue() + entry.getInterestAccrued().doubleValue() - entry.getInterestPaid().doubleValue();
31397 tejbeer 4377
 
31697 amit.gupta 4378
            long noOfdaysBetween = ChronoUnit.DAYS.between(entry.getDueDate().toLocalDate(), LocalDateTime.now());
31397 tejbeer 4379
 
31697 amit.gupta 4380
            CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());
31397 tejbeer 4381
 
35106 ranu 4382
            SDCreditRequirement sdCreditRequirement = sdCreditRequirementRepository.selectByFofoId(customRetailer.getPartnerId());
4383
 
31697 amit.gupta 4384
            sb.append("<tr>");
36303 aman 4385
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "</td>");
4386
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getCode() + "</td>");
33162 ranu 4387
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getAddress().getState() + "</td>");
33553 ranu 4388
            sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getArea() + "</td>");
4389
            sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getTerritory() + "</td>");
31886 tejbeer 4390
            sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getDueDate().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");
31697 amit.gupta 4391
            sb.append("<td style='border:1px solid black;padding: 5px'>" + noOfdaysBetween + "</td>");
35877 amit 4392
            sb.append("<td style='border:1px solid black;padding: 5px'>" + df.format(amount) + "</td>");
33161 ranu 4393
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL1Manager() + "</td>");
4394
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL2Manager() + "</td>");
4395
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getTerritoryManager() + "</td>");
4396
            sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getRegionalManager() + "</td>");
35521 amit 4397
            sb.append("<td style='border:1px solid black;padding: 5px'>" + df.format(sdCreditRequirement.getLimit()) + "</td>");
31697 amit.gupta 4398
            sb.append("</tr>");
4399
        }
31397 tejbeer 4400
 
31697 amit.gupta 4401
        sb.append("</tbody></table></body></html>");
31397 tejbeer 4402
 
31697 amit.gupta 4403
        return sb.toString();
4404
    }
31397 tejbeer 4405
 
32307 amit.gupta 4406
    public void notifyLoanDueDateCross() throws Exception {
31397 tejbeer 4407
 
35111 ranu 4408
        List<Loan> dueDateCrossLoans = sdCreditService.getDueDateCrossLoan();
4409
        List<Loan> allActiveLoans = sdCreditService.getAllActiveLoan();
31697 amit.gupta 4410
        if (!dueDateCrossLoans.isEmpty()) {
35521 amit 4411
            this.sendDueDateCrossLoanAlert(dueDateCrossLoans, allActiveLoans);
31697 amit.gupta 4412
        }
31397 tejbeer 4413
 
31697 amit.gupta 4414
    }
31397 tejbeer 4415
 
35521 amit 4416
    private void sendDueDateCrossLoanAlert(List<Loan> dueDateCrossLoans, List<Loan> allActiveLoans) throws Exception {
35591 aman 4417
        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 4418
 
35115 ranu 4419
        for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false).entrySet()) {
33631 tejus.loha 4420
            List<Loan> filteredRows = new ArrayList<>();
31697 amit.gupta 4421
            for (Loan loan : dueDateCrossLoans) {
30936 tejbeer 4422
 
31697 amit.gupta 4423
                if (storeGuyEntry.getValue().contains(loan.getFofoId())) {
30982 tejbeer 4424
 
31697 amit.gupta 4425
                    filteredRows.add(loan);
4426
                }
4427
            }
35111 ranu 4428
 
35112 ranu 4429
            List<Loan> filteredAllActiveLoans = new ArrayList<>();
35111 ranu 4430
            for (Loan loan : allActiveLoans) {
4431
 
4432
                if (storeGuyEntry.getValue().contains(loan.getFofoId())) {
4433
 
35112 ranu 4434
                    filteredAllActiveLoans.add(loan);
35111 ranu 4435
                }
4436
            }
4437
 
35112 ranu 4438
            ByteArrayOutputStream byteArrayOutputStream = null;
4439
            Utils.Attachment attachment1 = null;
35521 amit 4440
            if (!filteredAllActiveLoans.isEmpty()) {
4441
                byteArrayOutputStream = this.generateLoanCsv(filteredAllActiveLoans);
4442
                attachment1 = new Utils.Attachment("partnner-credit.csv", new ByteArrayResource(byteArrayOutputStream.toByteArray()));
35111 ranu 4443
 
4444
            }
4445
 
4446
 
31697 amit.gupta 4447
            if (!filteredRows.isEmpty()) {
4448
                String messageText = this.getMessageForDueDateCross(filteredRows);
35591 aman 4449
                String[] email = new String[]{storeGuyEntry.getKey(),"neeraj.gupta@smartdukaan.com"};
30982 tejbeer 4450
 
35521 amit 4451
                if (attachment1 != null) {
35959 amit 4452
                    mailOutboxService.queueMailWithAttachmentsViaGoogle(email, null, null, "Partner Credit Report", messageText, true, "ScheduledTasks.sendDueDateCrossLoanAlert", attachment1);
35521 amit 4453
                } else {
36460 ranu 4454
                    this.sendMailOfHtmlFormat(googleMailSender, email, messageText, null, "Due Date Cross");
30936 tejbeer 4455
 
35521 amit 4456
                }
4457
 
31697 amit.gupta 4458
            }
30936 tejbeer 4459
 
35115 ranu 4460
        }
35113 ranu 4461
 
4462
        String messageText = this.getMessageForDueDateCross(dueDateCrossLoans);
4463
        ByteArrayOutputStream byteArrayOutputStream = this.generateLoanCsv(allActiveLoans);
4464
        Utils.Attachment attachment = null;
35521 amit 4465
        if (byteArrayOutputStream != null) {
4466
            attachment = new Utils.Attachment("partnner-credit.csv", new ByteArrayResource(byteArrayOutputStream.toByteArray()));
35113 ranu 4467
 
31697 amit.gupta 4468
        }
33628 tejus.loha 4469
 
35521 amit 4470
        if (attachment != null) {
35959 amit 4471
            mailOutboxService.queueMailWithAttachmentsViaGoogle(new String[]{"sdtech@smartdukaan.com"}, null, null, "Partner Credit Report", messageText, true, "ScheduledTasks.sendDueDateCrossLoanAlert", attachment);
35521 amit 4472
        } else {
36460 ranu 4473
            this.sendMailOfHtmlFormat(googleMailSender, new String[]{"sdtech@smartdukaan.com"}, messageText, null, "Due Date Cross");
35113 ranu 4474
        }
33628 tejus.loha 4475
 
35111 ranu 4476
 
31697 amit.gupta 4477
        if (!dueDateCrossLoans.isEmpty()) {
4478
            for (Loan loan : dueDateCrossLoans) {
35877 amit 4479
                double principal = loan.getPendingAmount().doubleValue();
4480
                double interest = loan.getInterestAccrued().doubleValue() - loan.getInterestPaid().doubleValue();
4481
                double total = principal + interest;
30936 tejbeer 4482
 
31697 amit.gupta 4483
                String url = "http://app.smartdukaan.com/pages/home/credit";
30936 tejbeer 4484
 
35877 amit 4485
                String title = "Credit Payment Overdue!";
35915 amit 4486
                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 4487
 
31886 tejbeer 4488
                notificationService.sendNotification(loan.getFofoId(), title, MessageType.notification, title, message, url);
30936 tejbeer 4489
 
31697 amit.gupta 4490
            }
4491
        }
30982 tejbeer 4492
 
31697 amit.gupta 4493
    }
30936 tejbeer 4494
 
35112 ranu 4495
    private ByteArrayOutputStream generateLoanCsv(List<Loan> loans) throws ProfitMandiBusinessException {
4496
        org.apache.commons.io.output.ByteArrayOutputStream byteArrayOutputStream = null;
4497
 
4498
 
4499
        if (!loans.isEmpty()) {
4500
            Map<Integer, com.spice.profitmandi.dao.model.FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();
4501
            Map<Integer, FofoRBMReportingModel> fofoRbmReportingModelMap = csService.getPartnerIdRBMHeaders();
4502
            List<AST> asts = astRepository.selectAll();
4503
            Map<Integer, AST> astMap = asts.stream()
4504
                    .collect(Collectors.toMap(AST::getId, ast -> ast));
4505
            try {
4506
                List<String> headers = Arrays.asList(
4507
                        "PartnerName", "State Name", "Area", "Territory",
4508
                        "Due Date", "Days", "Pending Amount",
4509
                        "RBM L2", "RBM L1", "Sales L1", "Sales L2", "Limit Assigned"
4510
                );
4511
 
4512
                List<List<?>> rows = new ArrayList<>();
4513
 
35877 amit 4514
                DecimalFormat df = new DecimalFormat("#.##");
35112 ranu 4515
                for (Loan entry : loans) {
4516
 
35877 amit 4517
                    double amount = entry.getPendingAmount().doubleValue() + entry.getInterestAccrued().doubleValue() - entry.getInterestPaid().doubleValue();
35112 ranu 4518
 
35114 ranu 4519
                    long noOfdaysBetween = ChronoUnit.DAYS.between(entry.getCreatedOn().toLocalDate(), LocalDateTime.now());
35112 ranu 4520
 
4521
                    CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());
4522
                    SDCreditRequirement sdCreditRequirement = sdCreditRequirementRepository.selectByFofoId(customRetailer.getPartnerId());
4523
                    List<String> row = Arrays.asList(
4524
                            customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")",
4525
                            customRetailer.getAddress().getState(),
4526
                            astMap.get(customRetailer.getAstId()).getArea(),
4527
                            astMap.get(customRetailer.getAstId()).getTerritory(),
4528
                            entry.getDueDate().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")),
4529
                            String.valueOf(noOfdaysBetween),
35877 amit 4530
                            df.format(amount),
35112 ranu 4531
                            fofoRbmReportingModelMap.get(entry.getFofoId()).getL1Manager(),
4532
                            fofoRbmReportingModelMap.get(entry.getFofoId()).getL2Manager(),
4533
                            fofoReportingModelMap.get(entry.getFofoId()).getTerritoryManager(),
4534
                            fofoReportingModelMap.get(entry.getFofoId()).getRegionalManager(),
4535
                            df.format(sdCreditRequirement.getLimit())
4536
                    );
4537
 
4538
                    rows.add(row);
4539
                }
4540
 
4541
                byteArrayOutputStream = FileUtil.getCSVByteStream(headers, rows);
4542
 
4543
 
4544
            } catch (Exception e) {
4545
                throw new RuntimeException(e);
4546
            }
4547
 
4548
        }
4549
        return byteArrayOutputStream;
4550
    }
4551
 
4552
 
32307 amit.gupta 4553
    public void alertForDueDate() throws Exception {
30936 tejbeer 4554
 
31697 amit.gupta 4555
        List<Loan> loans = loanRepository.selectAllActiveLoan();
30936 tejbeer 4556
 
35877 amit 4557
        for (Loan loan : loans) {
4558
            long noOfdaysBetween = ChronoUnit.DAYS.between(LocalDate.now(), loan.getDueDate().toLocalDate());
30936 tejbeer 4559
 
35877 amit 4560
            LOGGER.info("noOfdaysBetween {} ", noOfdaysBetween);
30936 tejbeer 4561
 
35877 amit 4562
            if (noOfdaysBetween <= 4 && noOfdaysBetween >= 0) {
4563
                double amount = loan.getPendingAmount().doubleValue() + loan.getInterestAccrued().doubleValue() - loan.getInterestPaid().doubleValue();
30936 tejbeer 4564
 
35877 amit 4565
                String title = "Alert!";
4566
                String url = "http://app.smartdukaan.com/pages/home/credit";
4567
                String message;
4568
                if (noOfdaysBetween == 0) {
4569
                    message = "Your total outstanding Credit amount is Rs." + FormattingUtils.formatDecimal(amount) + " is due for Today, Pay Now!!";
4570
                } else {
4571
                    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 4572
                }
35877 amit 4573
                notificationService.sendNotification(loan.getFofoId(), title, MessageType.notification, title, message, url);
31697 amit.gupta 4574
            }
4575
        }
30984 tejbeer 4576
 
31697 amit.gupta 4577
    }
30982 tejbeer 4578
 
31697 amit.gupta 4579
    @Autowired
4580
    private HygieneDataRepository hygieneDataRepository;
31209 tejbeer 4581
 
31697 amit.gupta 4582
    public void hygineAlertForPartner() throws ProfitMandiBusinessException, MessagingException, IOException {
31206 tejbeer 4583
 
31697 amit.gupta 4584
        List<String> remarks = new ArrayList<>();
4585
        remarks.add("Out of Service");
4586
        remarks.add("Duplicate number");
4587
        remarks.add("Partner number");
31886 tejbeer 4588
        List<HygieneData> hygieneData = hygieneDataRepository.selectAllByDisposedDateAndRemark(LocalDate.now(), remarks);
31206 tejbeer 4589
 
31697 amit.gupta 4590
        if (!hygieneData.isEmpty()) {
31206 tejbeer 4591
 
31886 tejbeer 4592
            Map<Integer, List<HygieneData>> partnerHygieneDataMap = hygieneData.stream().collect(groupingBy(x -> x.getFofoId()));
31206 tejbeer 4593
 
31697 amit.gupta 4594
            for (Entry<Integer, List<HygieneData>> partnerHygieneDataMapEntry : partnerHygieneDataMap.entrySet()) {
31206 tejbeer 4595
 
31697 amit.gupta 4596
                CustomRetailer customRetailer = retailerService.getFofoRetailer(partnerHygieneDataMapEntry.getKey());
31206 tejbeer 4597
 
31697 amit.gupta 4598
                StringBuilder sb = new StringBuilder();
31886 tejbeer 4599
                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 4600
 
31886 tejbeer 4601
                        + " </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 4602
 
31697 amit.gupta 4603
                        + "<br/><table style='border:1px solid black ;padding: 5px';>");
4604
                sb.append("<tbody>\n" + "	" + "    				" + "<tr>\n");
4605
                sb.append("<th style='border:1px solid black;padding: 5px'>Invoice Number</th>\n");
4606
                sb.append("<th style='border:1px solid black;padding: 5px'>Customer Name</th>\n");
4607
                sb.append("<th style='border:1px solid black;padding: 5px'>Customer Number</th>\n");
4608
                sb.append("</tr>\n");
31206 tejbeer 4609
 
31697 amit.gupta 4610
                List<HygieneData> hygienes = partnerHygieneDataMapEntry.getValue();
31206 tejbeer 4611
 
31697 amit.gupta 4612
                List<Integer> orderIds = hygienes.stream().map(x -> x.getOrderId()).collect(Collectors.toList());
31206 tejbeer 4613
 
31697 amit.gupta 4614
                List<FofoOrder> fofoOrders = fofoOrderRepository.selectAllByOrderIds(orderIds);
31206 tejbeer 4615
 
31697 amit.gupta 4616
                for (FofoOrder fofoOrder : fofoOrders) {
4617
                    Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
4618
                    sb.append("<tr>");
31886 tejbeer 4619
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoOrder.getInvoiceNumber() + "</td>\n");
4620
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + customer.getFirstName() + "" + customer.getLastName() + "</td>\n");
4621
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + customer.getMobileNumber() + "</td>\n");
31206 tejbeer 4622
 
31697 amit.gupta 4623
                    sb.append("</tr>\n");
4624
                }
31206 tejbeer 4625
 
31697 amit.gupta 4626
                sb.append("</tbody></table></body></html>");
4627
                String subject = "Customer Info - Hygiene Alert";
31206 tejbeer 4628
 
36473 amit 4629
                this.sendMailOfHtmlFormat(googleMailSender, new String[]{customRetailer.getEmail()}, sb.toString(), null, subject);
31206 tejbeer 4630
 
31697 amit.gupta 4631
            }
31206 tejbeer 4632
 
31697 amit.gupta 4633
        }
31206 tejbeer 4634
 
31697 amit.gupta 4635
    }
31206 tejbeer 4636
 
33046 amit.gupta 4637
    //
4638
    public void setInventoryItemIdToPriceDropImei() {
4639
        List<PriceDropIMEI> priceDropIMEIList = priceDropIMEIRepository.selectAllMissingInventoryItemIds();
4640
        LOGGER.info("Problems with - {} entries", priceDropIMEIList.size());
4641
        //priceDropIMEIList.stream().collect(C)
4642
        for (PriceDropIMEI priceDropIMEI : priceDropIMEIList) {
4643
            System.out.println(priceDropIMEI.getImei());
4644
            List<InventoryItem> inventoryItems = inventoryItemRepository.selectAllBySerialNumberFofoId(priceDropIMEI.getImei(), priceDropIMEI.getPartnerId());
33051 amit.gupta 4645
            if (inventoryItems.size() == 0) {
33046 amit.gupta 4646
                LOGGER.info("Could not find Grn - FofoID {} , Imei {} ", priceDropIMEI);
33051 amit.gupta 4647
            } else if (inventoryItems.size() > 1) {
33046 amit.gupta 4648
                LOGGER.info("Found 2 such instance for - FofoID {} , Imei {} ", priceDropIMEI.getImei(), priceDropIMEI.getPartnerId());
4649
            } else {
4650
                priceDropIMEI.setInventoryItemId(inventoryItems.get(0).getId());
4651
            }
4652
 
4653
        }
4654
    }
4655
 
33051 amit.gupta 4656
    @Autowired
4657
    SaholicReservationSnapshotRepository saholicReservationSnapshotRepository;
4658
 
33256 amit.gupta 4659
    public void removePartialBillingForTransaction(int transactionId) throws ProfitMandiBusinessException {
35424 amit 4660
        // Fetch with pessimistic lock to prevent concurrent modifications
4661
        List<Order> orderList = orderRepository.selectAllByTransactionIdForUpdate(transactionId);
33051 amit.gupta 4662
        Map<Integer, Order> orderMap = orderList.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
4663
        //Delete scanRecords
4664
        List<WarehouseScan> warehouseScans = warehouseScanRepository.selectAllByOrderIds(new ArrayList<>(orderMap.keySet()));
4665
        for (WarehouseScan warehouseScan : warehouseScans) {
4666
            warehouseScanRepository.delete(warehouseScan);
4667
            WarehouseInventoryItem warehouseInventoryItem = warehouseInventoryItemRepository.selectById(warehouseScan.getInventoryItemId());
4668
            warehouseInventoryItem.setLastScanType(in.shop2020.warehouse.ScanType.PURCHASE);
4669
            warehouseInventoryItem.setCurrentQuantity(warehouseInventoryItem.getCurrentQuantity() + warehouseScan.getQuantity());
4670
        }
4671
 
4672
        for (Order order : orderList) {
33078 ranu 4673
            if (order.getBillingTimestamp() != null) {
33056 amit.gupta 4674
                order.setStatus(OrderStatus.ACCEPTED);
4675
                order.setStatusDescription("Submitted for Processing");
4676
                order.setBillingTimestamp(null);
4677
                order.setBilledBy(null);
33057 amit.gupta 4678
                order.setSerialNumber(null);
33056 amit.gupta 4679
                order.setJacketNumber(null);
33060 amit.gupta 4680
                order.getLineItem().setSerialNumber(null);
33056 amit.gupta 4681
                List<LineItemImei> lineItemImeis = lineItemImeisRepository.selectByLineItemId(order.getLineItem().getId());
4682
                for (LineItemImei lineItemImei : lineItemImeis) {
4683
                    lineItemImeisRepository.delete(lineItemImei);
4684
                }
4685
                SaholicReservationSnapshot saholicReservationSnapshot = saholicReservationSnapshotRepository
4686
                        .selectByOrderId(order.getId());
4687
                if (saholicReservationSnapshot == null) {
4688
                    saholicInventoryService.addReservationCount(order.getLineItem().getItemId(),
4689
                            order.getFulfilmentWarehouseId(), order.getLineItem().getQuantity(), order.getId());
4690
                }
33055 amit.gupta 4691
            }
33051 amit.gupta 4692
        }
4693
    }
4694
 
31697 amit.gupta 4695
    public void hygineAlertForInternalTeam() throws ProfitMandiBusinessException, MessagingException, IOException {
31206 tejbeer 4696
 
31697 amit.gupta 4697
        List<String> remarks = new ArrayList<>();
4698
        remarks.add("Out of Service");
4699
        remarks.add("Duplicate number");
4700
        remarks.add("Partner number");
31886 tejbeer 4701
        List<HygieneData> hygieneDataLastThreeMonth = hygieneDataRepository.selectDisposedDateAndRemarks(
4702
                LocalDate.now().withDayOfMonth(1).minusMonths(3).atStartOfDay(), LocalDate.now().minusMonths(1).withDayOfMonth(LocalDate.now().minusMonths(1).lengthOfMonth()).atTime(LocalTime.MAX), remarks);
31206 tejbeer 4703
 
31886 tejbeer 4704
        List<HygieneData> hygieneDataRecentMonth = hygieneDataRepository.selectDisposedDateAndRemarks(LocalDate.now().withDayOfMonth(1), remarks);
31697 amit.gupta 4705
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
4706
        Map<Integer, List<HygieneData>> partnerHygieneLastThreeMonthMap = null;
31206 tejbeer 4707
 
31697 amit.gupta 4708
        Map<Integer, List<HygieneData>> partnerHygieneDataRecentMonth = null;
31206 tejbeer 4709
 
31697 amit.gupta 4710
        if (!hygieneDataLastThreeMonth.isEmpty()) {
31886 tejbeer 4711
            partnerHygieneLastThreeMonthMap = hygieneDataLastThreeMonth.stream().collect(groupingBy(x -> x.getFofoId()));
31206 tejbeer 4712
 
31697 amit.gupta 4713
        }
31206 tejbeer 4714
 
31697 amit.gupta 4715
        if (!hygieneDataRecentMonth.isEmpty()) {
31886 tejbeer 4716
            partnerHygieneDataRecentMonth = hygieneDataRecentMonth.stream().collect(groupingBy(x -> x.getFofoId()));
31697 amit.gupta 4717
        }
31206 tejbeer 4718
 
31697 amit.gupta 4719
        for (Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {
31206 tejbeer 4720
 
31697 amit.gupta 4721
            String email = storeGuyEntry.getKey();
31206 tejbeer 4722
 
31697 amit.gupta 4723
            List<Integer> fofoIds = new ArrayList<>(storeGuyEntry.getValue());
31206 tejbeer 4724
 
31697 amit.gupta 4725
            Map<Integer, Map<YearMonth, List<HygieneData>>> partnerYearMonthData = new HashMap<>();
4726
            Map<Integer, Map<LocalDate, List<HygieneData>>> partnerDateWiseData = new HashMap<>();
4727
            for (Integer fofoId : fofoIds) {
31206 tejbeer 4728
 
31697 amit.gupta 4729
                partnerYearMonthData.put(fofoId, null);
4730
                partnerDateWiseData.put(fofoId, null);
4731
                if (!partnerHygieneLastThreeMonthMap.isEmpty()) {
4732
                    List<HygieneData> hygienes = partnerHygieneLastThreeMonthMap.get(fofoId);
31206 tejbeer 4733
 
31697 amit.gupta 4734
                    if (hygienes != null) {
31886 tejbeer 4735
                        Map<YearMonth, List<HygieneData>> yearMonthData = hygienes.stream().collect(groupingBy(x -> YearMonth.from(x.getDisposedTimestamp())));
31206 tejbeer 4736
 
31697 amit.gupta 4737
                        partnerYearMonthData.put(fofoId, yearMonthData);
31206 tejbeer 4738
 
31697 amit.gupta 4739
                    }
4740
                    List<HygieneData> dateWiseHygienes = partnerHygieneDataRecentMonth.get(fofoId);
31206 tejbeer 4741
 
31697 amit.gupta 4742
                    if (dateWiseHygienes != null) {
31206 tejbeer 4743
 
31886 tejbeer 4744
                        Map<LocalDate, List<HygieneData>> dateWiseData = hygienes.stream().collect(groupingBy(x -> (x.getDisposedTimestamp()).toLocalDate()));
31206 tejbeer 4745
 
31697 amit.gupta 4746
                        partnerDateWiseData.put(fofoId, dateWiseData);
31206 tejbeer 4747
 
31697 amit.gupta 4748
                    }
31206 tejbeer 4749
 
31697 amit.gupta 4750
                }
31206 tejbeer 4751
 
31697 amit.gupta 4752
            }
31206 tejbeer 4753
 
31697 amit.gupta 4754
            String subject = "Customer Info - Hygiene Alert";
31206 tejbeer 4755
 
31697 amit.gupta 4756
            LOGGER.info("hygieneData {}", partnerDateWiseData.values());
31206 tejbeer 4757
 
31697 amit.gupta 4758
            boolean partnerDateWise = partnerDateWiseData.values().stream().allMatch(Objects::isNull);
31206 tejbeer 4759
 
31697 amit.gupta 4760
            boolean partnerYearMonth = partnerYearMonthData.values().stream().allMatch(Objects::isNull);
31206 tejbeer 4761
 
31697 amit.gupta 4762
            if (!partnerDateWise && !partnerYearMonth) {
4763
                String sb = this.getMessageHygieneAlertForPartner(partnerYearMonthData, partnerDateWiseData);
36460 ranu 4764
                this.sendMailOfHtmlFormat(googleMailSender, new String[]{email}, sb, null, subject);
31697 amit.gupta 4765
            }
31206 tejbeer 4766
 
31697 amit.gupta 4767
        }
31206 tejbeer 4768
 
31697 amit.gupta 4769
    }
31206 tejbeer 4770
 
31697 amit.gupta 4771
    private String getMessageHygieneAlertForPartner(
33256 amit.gupta 4772
            Map<Integer, Map<YearMonth, List<HygieneData>>> partnerYearMonthData, Map<Integer, Map<LocalDate, List<HygieneData>>> partnerDateWiseData)
4773
            throws ProfitMandiBusinessException {
31206 tejbeer 4774
 
31697 amit.gupta 4775
        Map<Integer, CustomRetailer> customeRetailerMap = retailerService.getAllFofoRetailers();
31206 tejbeer 4776
 
31697 amit.gupta 4777
        LocalDateTime startDate = LocalDate.now().withDayOfMonth(1).atStartOfDay();
4778
        LocalDateTime endDate = LocalDateTime.now();
31206 tejbeer 4779
 
31697 amit.gupta 4780
        LocalDateTime startYearMonth = LocalDate.now().withDayOfMonth(1).minusMonths(3).atStartOfDay();
31886 tejbeer 4781
        LocalDateTime endYearMonth = LocalDate.now().minusMonths(1).withDayOfMonth(LocalDate.now().minusMonths(1).lengthOfMonth()).atTime(LocalTime.MAX);
31206 tejbeer 4782
 
31697 amit.gupta 4783
        DateTimeFormatter dateYearMonthFormatter = DateTimeFormatter.ofPattern("MMM''uu");
31206 tejbeer 4784
 
31697 amit.gupta 4785
        List<YearMonth> yearMonthRange = new ArrayList<>();
4786
        yearMonthRange.add(YearMonth.from(startYearMonth));
31206 tejbeer 4787
 
31697 amit.gupta 4788
        yearMonthRange.add(YearMonth.from(startYearMonth.plusMonths(1)));
31206 tejbeer 4789
 
31697 amit.gupta 4790
        yearMonthRange.add(YearMonth.from(endYearMonth));
31206 tejbeer 4791
 
31697 amit.gupta 4792
        long noOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate.plusDays(1));
31206 tejbeer 4793
 
31886 tejbeer 4794
        List<LocalDate> dateRange = Stream.iterate(startDate.toLocalDate(), date -> date.plusDays(1)).limit(noOfDaysBetween).collect(Collectors.toList());
31206 tejbeer 4795
 
31697 amit.gupta 4796
        StringBuilder sb = new StringBuilder();
31886 tejbeer 4797
        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 4798
 
31697 amit.gupta 4799
                + "<table style='border:1px solid black ;padding: 5px';>");
4800
        sb.append("<tbody>\n" + "	" + "    				" + "<tr>\n");
4801
        sb.append("<th style='border:1px solid black;padding: 5px'>Partner Name</th>\n");
31206 tejbeer 4802
 
31697 amit.gupta 4803
        for (YearMonth yearMonth : yearMonthRange) {
31886 tejbeer 4804
            sb.append("<th style='border:1px solid black;padding: 5px'>" + yearMonth.format(dateYearMonthFormatter) + "</th>\n");
31697 amit.gupta 4805
        }
31206 tejbeer 4806
 
31697 amit.gupta 4807
        for (LocalDate localDate : dateRange) {
4808
            sb.append("<th style='border:1px solid black;padding: 5px'>" + localDate + "</th>\n");
4809
        }
31206 tejbeer 4810
 
31697 amit.gupta 4811
        sb.append("</tr>\n");
31206 tejbeer 4812
 
31886 tejbeer 4813
        for (Entry<Integer, Map<YearMonth, List<HygieneData>>> partnerYearMonthEntry : partnerYearMonthData.entrySet()) {
31206 tejbeer 4814
 
31697 amit.gupta 4815
            int fofoId = partnerYearMonthEntry.getKey();
31206 tejbeer 4816
 
31697 amit.gupta 4817
            Map<YearMonth, List<HygieneData>> yearMonthData = partnerYearMonthEntry.getValue();
31206 tejbeer 4818
 
31697 amit.gupta 4819
            Map<LocalDate, List<HygieneData>> dateWiseData = partnerDateWiseData.get(fofoId);
31206 tejbeer 4820
 
31697 amit.gupta 4821
            if (yearMonthData == null && dateWiseData == null) {
4822
                continue;
4823
            }
31206 tejbeer 4824
 
31697 amit.gupta 4825
            sb.append("<tr>");
31886 tejbeer 4826
            sb.append("<td style='border:1px solid black;padding: 5px'>" + customeRetailerMap.get(fofoId).getBusinessName() + "</td>\n");
31697 amit.gupta 4827
            for (YearMonth yearMonth : yearMonthRange) {
31206 tejbeer 4828
 
31697 amit.gupta 4829
                if (yearMonthData == null) {
4830
                    sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");
31206 tejbeer 4831
 
31697 amit.gupta 4832
                } else {
4833
                    List<HygieneData> hygieneList = yearMonthData.get(yearMonth);
31206 tejbeer 4834
 
31697 amit.gupta 4835
                    if (hygieneList != null) {
4836
                        sb.append("<td style='border:1px solid black;padding: 5px'>" + hygieneList.size() + "</td>\n");
31206 tejbeer 4837
 
31697 amit.gupta 4838
                    } else {
4839
                        sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");
31206 tejbeer 4840
 
31697 amit.gupta 4841
                    }
4842
                }
4843
            }
31206 tejbeer 4844
 
31697 amit.gupta 4845
            for (LocalDate localDate : dateRange) {
31206 tejbeer 4846
 
31697 amit.gupta 4847
                if (dateWiseData == null) {
4848
                    sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");
31206 tejbeer 4849
 
31697 amit.gupta 4850
                } else {
4851
                    List<HygieneData> hygieneList = dateWiseData.get(localDate);
31206 tejbeer 4852
 
31697 amit.gupta 4853
                    if (hygieneList != null) {
4854
                        sb.append("<td style='border:1px solid black;padding: 5px'>" + hygieneList.size() + "</td>\n");
31218 tejbeer 4855
 
31697 amit.gupta 4856
                    } else {
4857
                        sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");
31218 tejbeer 4858
 
31697 amit.gupta 4859
                    }
4860
                }
4861
            }
4862
            sb.append("</tr>");
31218 tejbeer 4863
 
31697 amit.gupta 4864
        }
31218 tejbeer 4865
 
31697 amit.gupta 4866
        sb.append("</tbody></table></body></html>");
31218 tejbeer 4867
 
31697 amit.gupta 4868
        return sb.toString();
4869
    }
31218 tejbeer 4870
 
33874 ranu 4871
    @Autowired
4872
    private MonthlyTargetRepository monthlyTargetRepository;
31218 tejbeer 4873
 
31697 amit.gupta 4874
    public void monthlyTargetForPartner() throws MessagingException, ProfitMandiBusinessException, IOException {
31218 tejbeer 4875
 
31697 amit.gupta 4876
        LocalDateTime curDate = LocalDateTime.now();
4877
        List<MonthlyTarget> monthlyTargets = monthlyTargetRepository.selectByDate(YearMonth.now());
31218 tejbeer 4878
 
31886 tejbeer 4879
        Map<Integer, MonthlyTarget> partnersMonthlyTarget = monthlyTargets.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
31218 tejbeer 4880
 
31886 tejbeer 4881
        Map<Integer, Double> secondaryMtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));
4882
        Map<Integer, Double> todaytertiary = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate, curDate.with(LocalTime.MAX), 0, false);
31218 tejbeer 4883
 
31697 amit.gupta 4884
        String subject = "Monthly Target Vs Achievement";
31218 tejbeer 4885
 
31697 amit.gupta 4886
        for (Entry<Integer, MonthlyTarget> partnerMonthlyTargetEntry : partnersMonthlyTarget.entrySet()) {
31249 tejbeer 4887
 
31697 amit.gupta 4888
            int fofoId = partnerMonthlyTargetEntry.getKey();
31249 tejbeer 4889
 
31697 amit.gupta 4890
            CustomRetailer customRetailer = retailerService.getFofoRetailer(fofoId);
31249 tejbeer 4891
 
31697 amit.gupta 4892
            Double purchaseTarget = partnerMonthlyTargetEntry.getValue().getPurchaseTarget();
31218 tejbeer 4893
 
31697 amit.gupta 4894
            Double saleTarget = partnerMonthlyTargetEntry.getValue().getSaleTarget();
31218 tejbeer 4895
 
31697 amit.gupta 4896
            if (purchaseTarget > 0) {
4897
                Double purchase = secondaryMtd.get(fofoId);
31249 tejbeer 4898
 
31697 amit.gupta 4899
                if (purchase == null) {
4900
                    purchase = 0.0;
4901
                }
31218 tejbeer 4902
 
31697 amit.gupta 4903
                Double balanceTarget = purchaseTarget - purchase;
31218 tejbeer 4904
 
31697 amit.gupta 4905
                if (balanceTarget <= 0) {
4906
                    balanceTarget = 0.0;
4907
                }
31651 tejbeer 4908
 
31697 amit.gupta 4909
                StringBuilder sb = new StringBuilder();
4910
                sb.append("<html><body><p>Dear Partner,\n");
31886 tejbeer 4911
                sb.append("<p>Pls note your agreed monthly target is Rs." + purchaseTarget + " and your achievement till date is Rs." + purchase + "</p>");
31697 amit.gupta 4912
                sb.append("<p>Pls note that your balance target is Rs." + balanceTarget + "</p>\n");
4913
                sb.append(
32350 amit.gupta 4914
                        "<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 4915
 
36473 amit 4916
                this.sendMailOfHtmlFormat(googleMailSender, new String[]{customRetailer.getEmail()}, sb.toString(), null, subject);
31697 amit.gupta 4917
            }
31218 tejbeer 4918
 
31697 amit.gupta 4919
        }
31218 tejbeer 4920
 
31697 amit.gupta 4921
    }
31218 tejbeer 4922
 
33444 ranu 4923
 
34502 amit.gupta 4924
    public void findAllLiveDemoBrandItemsByBillingDate() throws
4925
            MessagingException, ProfitMandiBusinessException, IOException {
33444 ranu 4926
        LocalDateTime endDate = LocalDate.now().atStartOfDay().minusDays(8);
4927
 
4928
        List<LiveDemoOrderLineItemModel> liveDemoOrderLineItemModels = orderRepository.findAllLiveDemoBrandItemsByBillingDate(endDate.minusDays(60), endDate);
4929
        LOGGER.info("liveDemoOrderLineItemModels {}", liveDemoOrderLineItemModels);
4930
        String subject = "Billed Live Demo Model";
4931
        StringBuilder sb = new StringBuilder();
4932
 
4933
        sb.append("<html><body><p>Hi,\n");
4934
        sb.append("<p>Please check live demo billed order :</p>\n" + " <table style='border:1px solid black ;padding: 5px; border-collapse: collapse;'>");
4935
 
4936
        sb.append("<th style='border:1px solid black;padding: 5px'>Item Id</th>\n");
4937
        sb.append("<th style='border:1px solid black;padding: 5px'>Invoice Number</th>\n");
4938
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
4939
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
4940
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
4941
        sb.append("<th style='border:1px solid black;padding: 5px'>Serial Number</th>\n");
4942
        sb.append("<th style='border:1px solid black;padding: 5px'>Retailer Name</th>\n");
4943
        sb.append("<th style='border:1px solid black;padding: 5px'>Retailer City</th>\n");
4944
        sb.append("<th style='border:1px solid black;padding: 5px'>Retailer Pincode</th>\n");
4945
        sb.append("<th style='border:1px solid black;padding: 5px'>Retailer State</th>\n");
4946
        sb.append("<th style='border:1px solid black;padding: 5px'>Billing Date</th>\n");
4947
        sb.append("</tr>\n");
4948
        for (LiveDemoOrderLineItemModel liveDemoModel : liveDemoOrderLineItemModels) {
4949
            sb.append("<tr>");
4950
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getItemId() + "</td>\n");
4951
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getInvoiceNumber() + "</td>\n");
4952
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getBrand() + "</td>\n");
4953
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getModelNumber() + "</td>\n");
4954
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getModelName() + "</td>\n");
4955
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getSerialNumber() + "</td>\n");
4956
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getRetailerName() + "</td>\n");
4957
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getRetailerCity() + "</td>\n");
4958
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getRetailerPincode() + "</td>\n");
4959
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getState() + "</td>\n");
4960
            sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getFormattedBillingDate() + "</td>\n");
4961
 
4962
            sb.append("</tr>\n");
4963
 
33506 amit.gupta 4964
        }
33444 ranu 4965
        List<String> sendTo = Arrays.asList("kamini.sharma@smartdukaan.com", "niranjan.kala@smartdukaan.com",
33506 amit.gupta 4966
                "mohit.gulati@smartdukaan.com", "vinay.p@smartdukaan.com", "shivam.gupta@smartdukaan.com");
33444 ranu 4967
 
4968
 
4969
        String[] email = sendTo.toArray(new String[sendTo.size()]);
36476 amit 4970
    this.sendMailOfHtmlFormat(googleMailSender, email, sb.toString(), null, subject);
33444 ranu 4971
 
4972
    }
4973
 
33464 ranu 4974
    public void findTodayPocoBillingItems() throws MessagingException, ProfitMandiBusinessException, IOException {
4975
        LocalDateTime endDate = LocalDate.now().atStartOfDay().plusDays(1);
4976
        LocalDateTime startDate = LocalDate.now().atStartOfDay().minusDays(1);
33444 ranu 4977
 
33464 ranu 4978
        List<LiveDemoOrderLineItemModel> pocoBillingOrderLineItemModels = orderRepository.findTodayPocoBillingItems(startDate, endDate);
4979
        LOGGER.info("pocoBillingOrderLineItemModels {}", pocoBillingOrderLineItemModels);
4980
        String subject = "Poco Billing";
4981
        StringBuilder sb = new StringBuilder();
4982
 
4983
        sb.append("<html><body><p>Hi,\n");
4984
        sb.append("<p>Please check poco billed order :</p>\n" + " <table style='border:1px solid black ;padding: 5px; border-collapse: collapse;'>");
4985
 
4986
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
4987
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
4988
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
4989
        sb.append("<th style='border:1px solid black;padding: 5px'>Serial Number</th>\n");
4990
        sb.append("<th style='border:1px solid black;padding: 5px'>Retailer State</th>\n");
4991
        sb.append("<th style='border:1px solid black;padding: 5px'>Billing Date</th>\n");
4992
        sb.append("</tr>\n");
4993
        for (LiveDemoOrderLineItemModel pocoModel : pocoBillingOrderLineItemModels) {
4994
            sb.append("<tr>");
4995
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getBrand() + "</td>\n");
4996
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getModelNumber() + "</td>\n");
4997
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getModelName() + "</td>\n");
4998
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getSerialNumber() + "</td>\n");
4999
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getState() + "</td>\n");
5000
            sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getFormattedBillingDate() + "</td>\n");
5001
 
5002
            sb.append("</tr>\n");
5003
 
33506 amit.gupta 5004
        }
36936 vikas 5005
        List<String> sendTo = Arrays.asList("uday.singh@smartdukaan.com", "kuldeep.kumar@smartdukaan.com", "ritesh.chauhan1@smartdukaan.com");
33464 ranu 5006
 
5007
        String[] email = sendTo.toArray(new String[sendTo.size()]);
36473 amit 5008
        this.sendMailOfHtmlFormat(googleMailSender, email, sb.toString(), null, subject);
33464 ranu 5009
 
5010
    }
5011
 
5012
 
31697 amit.gupta 5013
    public void monthlyTargetForInternalTeam() throws MessagingException, ProfitMandiBusinessException, IOException {
31218 tejbeer 5014
 
31697 amit.gupta 5015
        LocalDateTime curDate = LocalDateTime.now();
31218 tejbeer 5016
 
34903 ranu 5017
        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 5018
 
31697 amit.gupta 5019
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false);
31218 tejbeer 5020
 
31697 amit.gupta 5021
        List<MonthlyTarget> monthlyTargets = monthlyTargetRepository.selectByDate(YearMonth.now());
31218 tejbeer 5022
 
31697 amit.gupta 5023
        Map<Integer, CustomRetailer> customeRetailerMap = retailerService.getAllFofoRetailers();
31218 tejbeer 5024
 
31886 tejbeer 5025
        Map<Integer, MonthlyTarget> partnersMonthlyTarget = monthlyTargets.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
31218 tejbeer 5026
 
31886 tejbeer 5027
        Map<Integer, Double> secondaryMtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));
5028
        Map<Integer, Double> todaytertiary = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate, curDate.with(LocalTime.MAX), 0, false);
31218 tejbeer 5029
 
31697 amit.gupta 5030
        String subject = "Monthly Target Vs Achievement";
31218 tejbeer 5031
 
31697 amit.gupta 5032
        for (Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {
31218 tejbeer 5033
 
31697 amit.gupta 5034
            String email = storeGuyEntry.getKey();
31218 tejbeer 5035
 
31697 amit.gupta 5036
            List<Integer> fofoIds = new ArrayList<>(storeGuyEntry.getValue());
5037
            Map<Integer, MonthlyTarget> monthlyTargetAchievement = new HashMap<>();
5038
            for (Integer fofoId : fofoIds) {
31218 tejbeer 5039
 
31697 amit.gupta 5040
                MonthlyTarget monthlyTarget = partnersMonthlyTarget.get(fofoId);
5041
                if (monthlyTarget != null) {
5042
                    Double purchaseTarget = monthlyTarget.getPurchaseTarget();
31218 tejbeer 5043
 
31697 amit.gupta 5044
                    Double saleTarget = monthlyTarget.getSaleTarget();
31218 tejbeer 5045
 
31697 amit.gupta 5046
                    if (purchaseTarget != null && purchaseTarget > 0) {
5047
                        Double purchase = secondaryMtd.get(fofoId);
5048
                        if (purchase == null) {
5049
                            purchase = 0.0;
5050
                        }
5051
                        monthlyTarget.setPurchaseAchievement(purchase);
5052
                        monthlyTargetAchievement.put(fofoId, monthlyTarget);
31218 tejbeer 5053
 
31697 amit.gupta 5054
                    }
5055
                }
5056
            }
31218 tejbeer 5057
 
31697 amit.gupta 5058
            if (!monthlyTargetAchievement.isEmpty()) {
31218 tejbeer 5059
 
31697 amit.gupta 5060
                StringBuilder sb = new StringBuilder();
31218 tejbeer 5061
 
31697 amit.gupta 5062
                sb.append("<html><body><p>Hi,\n");
31886 tejbeer 5063
                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 5064
                sb.append("<tbody>\n" + "	" + "    				" + "<tr>\n");
5065
                sb.append("<th style='border:1px solid black;padding: 5px'>Partner Name</th>\n");
31218 tejbeer 5066
 
31697 amit.gupta 5067
                sb.append("<th style='border:1px solid black;padding: 5px'>Purchase Target</th>\n");
31218 tejbeer 5068
 
31697 amit.gupta 5069
                sb.append("<th style='border:1px solid black;padding: 5px'>Purchase Achievement</th>\n");
5070
                sb.append("</tr>\n");
31218 tejbeer 5071
 
31886 tejbeer 5072
                for (Entry<Integer, MonthlyTarget> monthlyTargetAchievementEntry : monthlyTargetAchievement.entrySet()) {
31697 amit.gupta 5073
                    sb.append("<tr>");
5074
                    int fofoId = monthlyTargetAchievementEntry.getKey();
31218 tejbeer 5075
 
31697 amit.gupta 5076
                    MonthlyTarget monthlyTarget = monthlyTargetAchievementEntry.getValue();
31886 tejbeer 5077
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + customeRetailerMap.get(fofoId).getBusinessName() + "</td>\n");
31218 tejbeer 5078
 
31886 tejbeer 5079
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + monthlyTarget.getPurchaseTarget() + "</td>\n");
31218 tejbeer 5080
 
31886 tejbeer 5081
                    sb.append("<td style='border:1px solid black;padding: 5px'>" + monthlyTarget.getPurchaseAchievement() + "</td>\n");
31218 tejbeer 5082
 
31697 amit.gupta 5083
                    sb.append("</tr>\n");
31218 tejbeer 5084
 
31697 amit.gupta 5085
                }
31218 tejbeer 5086
 
36460 ranu 5087
                this.sendMailOfHtmlFormat(googleMailSender, new String[]{email}, sb.toString(), null, subject);
31697 amit.gupta 5088
                // this.sendMailOfHtmlFormat("tejbeer.kaur@smartdukaan.com", sb.toString(),
5089
                // null, subject);
31218 tejbeer 5090
 
31697 amit.gupta 5091
            }
31604 tejbeer 5092
 
31697 amit.gupta 5093
        }
31604 tejbeer 5094
 
31697 amit.gupta 5095
    }
31604 tejbeer 5096
 
32061 amit.gupta 5097
    @Autowired
5098
    private PerformanceService performanceService;
5099
 
5100
 
5101
    public void sendFilteredRetailerPerformance() throws Exception {
5102
        RetailerFilterModel retailerFilterModel = performanceService.getRetailerFilterModel();
5103
 
5104
        Map<Integer, CustomRetailer> customRetailers = retailerService.getFofoRetailers(true);
5105
 
5106
 
5107
        List<RetailerPeformanceFilterModel> partnersPerformance = performanceService.getPerformance(retailerFilterModel, customRetailers);
5108
 
5109
        Map<Integer, RetailerPeformanceFilterModel> partnersPerformanceMap = new HashMap<>();
5110
 
5111
        if (!partnersPerformance.isEmpty()) {
5112
            partnersPerformanceMap = partnersPerformance.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
5113
            performanceService.sendPartnerPerformanceEmail(partnersPerformanceMap, retailerFilterModel, customRetailers);
5114
 
5115
        }
5116
 
5117
 
5118
    }
5119
 
32081 tejbeer 5120
    @Autowired
5121
    private VendorItemPricingRepository vendorItemPricingRepository;
32061 amit.gupta 5122
 
32081 tejbeer 5123
 
5124
    @Autowired
5125
    private VendorCatalogPricingService vendorCatalogPricingService;
5126
 
5127
 
33256 amit.gupta 5128
    public void migrateVendorItemPricing() throws ProfitMandiBusinessException {
32081 tejbeer 5129
 
5130
        List<VendorItemPricing> vendorItemPricings = vendorItemPricingRepository.selectAll();
32350 amit.gupta 5131
        LOGGER.info("At migrate VendorItemPricing");
32092 tejbeer 5132
        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 5133
        for (VendorItemPricing vendorItemPricing : vendorItemPricings) {
5134
            Item item = null;
32092 tejbeer 5135
            if (items.get(vendorItemPricing.getItemId()) != null) {
5136
                item = items.get(vendorItemPricing.getItemId());
5137
            } else {
32084 tejbeer 5138
                continue;
32081 tejbeer 5139
            }
32092 tejbeer 5140
 
32081 tejbeer 5141
            VendorCatalogPricingModel vendorCatalogPricingModel = new VendorCatalogPricingModel();
5142
            vendorCatalogPricingModel.setCatalogId(item.getCatalogItemId());
5143
            vendorCatalogPricingModel.setAuthId(13);
32088 tejbeer 5144
            vendorCatalogPricingModel.setDp(vendorItemPricing.getDp());
32081 tejbeer 5145
 
5146
            vendorCatalogPricingModel.setTp(vendorItemPricing.getTp());
5147
            vendorCatalogPricingModel.setMop(vendorItemPricing.getMop());
32384 amit.gupta 5148
            vendorCatalogPricingModel.setEffectedOn(LocalDate.of(2023, 8, 22));
32081 tejbeer 5149
            vendorCatalogPricingModel.setVendorId(vendorItemPricing.getVendorId());
5150
 
5151
 
5152
            try {
5153
                vendorCatalogPricingService.createVendorCatalogPricingLog(vendorCatalogPricingModel);
5154
            } catch (ProfitMandiBusinessException e) {
5155
                continue;
5156
            }
5157
 
5158
        }
5159
 
5160
    }
5161
 
5162
    public void approveVendorCatalogPricing() {
5163
        List<VendorCatalogPricingLog> vendorCatalogPricingLogs = vendorCatalogPricingLogRepository.selectByStatus(VendorCatalogPricingStatus.PENDING);
5164
 
32084 tejbeer 5165
 
32081 tejbeer 5166
        for (VendorCatalogPricingLog vendorCatalogPricingLog : vendorCatalogPricingLogs) {
32107 tejbeer 5167
            vendorCatalogPricingLog.setStatus(VendorCatalogPricingStatus.APPROVED);
5168
            vendorCatalogPricingLog.setUpdatedTimestamp(LocalDateTime.now());
5169
            vendorCatalogPricingLog.setApprovedBy(13);
5170
            vendorCatalogPricingLog.setApprovedTimestamp(LocalDateTime.now());
32114 tejbeer 5171
            vendorCatalogPricingService.createVendorCatalogPricing(vendorCatalogPricingLog);
5172
        }
32081 tejbeer 5173
 
32114 tejbeer 5174
    }
32108 tejbeer 5175
 
32822 ranu 5176
    public void sendMailWhatsAppAfterLoanDueDate() throws Exception {
36289 amit 5177
        synchronized (SD_CREDIT_LOCK) {
5178
            sdCreditService.updateRisk();
5179
            List<Loan> defaultLoans = sdCreditService.getDefaultLoans();
5180
            if (!defaultLoans.isEmpty()) {
5181
                this.sendLoanAlert(defaultLoans);
5182
            }
32822 ranu 5183
        }
5184
    }
5185
 
5186
    public void sendLoanAlert(List<Loan> defaultLoans) throws
5187
            Exception {
5188
 
35877 amit 5189
        // Sort by lowest dueDate first (most overdue)
5190
        defaultLoans.sort(Comparator.comparing(Loan::getDueDate));
32822 ranu 5191
 
35877 amit 5192
        int whatsAppCount = 0;
32822 ranu 5193
        for (Loan defaultLoan : defaultLoans) {
35877 amit 5194
            double principal = defaultLoan.getPendingAmount().doubleValue();
5195
            double interest = defaultLoan.getInterestAccrued().doubleValue() - defaultLoan.getInterestPaid().doubleValue();
5196
            double total = principal + interest;
32822 ranu 5197
 
5198
            com.spice.profitmandi.dao.entity.user.User user = userUserRepository.selectById(defaultLoan.getFofoId());
5199
 
5200
            Address address = addressRepository.selectById(user.getAddressId());
5201
 
37417 vikas 5202
            // WhatsApp: only top 2 most overdue loans. Days in default and the penalty rate are fixed
5203
            // copy in the approved template, so only the name and the amount are sent.
35877 amit 5204
            if (whatsAppCount < 2) {
37417 vikas 5205
                notificationService.sendLoanDefaultAlert(address.getPhoneNumber(), user.getName(),
5206
                        FormattingUtils.formatDecimal(total));
35877 amit 5207
                whatsAppCount++;
32850 amit.gupta 5208
            }
5209
 
35877 amit 5210
            String emailMessage = getEmailMessageForDefaultLoan(defaultLoan, principal, interest, total, user.getName());
32822 ranu 5211
            String[] email = {user.getEmailId()};
36473 amit 5212
            sendMailOfHtmlFormat(googleMailSender, email, emailMessage, null, "Loan Alert - SmartDukaan");
32822 ranu 5213
        }
5214
    }
5215
 
35877 amit 5216
    private String getEmailMessageForDefaultLoan(Loan loan, double principal, double interest, double total, String name) {
5217
        String formattedTotal = FormattingUtils.formatDecimal(total);
5218
        String formattedPrincipal = FormattingUtils.formatDecimal(principal);
5219
        String formattedInterest = FormattingUtils.formatDecimal(interest);
5220
        long daysInDefault = ChronoUnit.DAYS.between(loan.getPenaltyDate(), LocalDate.now());
32822 ranu 5221
 
5222
        StringBuilder sb = new StringBuilder();
35877 amit 5223
        sb.append("<html><body>");
5224
        sb.append("<p><b>Credit Default Alert!</b></p><br/>");
5225
        sb.append("<p>Dear " + name + ",</p>");
5226
        sb.append("<p>Your credit payment has been in default for " + daysInDefault + " days. " +
35915 amit 5227
                "A penalty interest of " + (loan.getPenaltyRate() != null ? loan.getPenaltyRate() : ProfitMandiConstants.NEW_DELAYED_INTEREST_RATE) + "% per day is being charged.</p>");
35877 amit 5228
        sb.append("<p><b>Total Outstanding: Rs. " + formattedTotal + "</b><br/>");
5229
        sb.append("Principal: Rs. " + formattedPrincipal + "<br/>");
5230
        sb.append("Interest: Rs. " + formattedInterest + "</p>");
5231
        sb.append("<p>Continued default will impact your Credit score and may result in legal action. " +
5232
                "Please settle the outstanding amount immediately.</p>");
5233
        sb.append("<p>To make the payment, please add Rs. " + formattedTotal + " to your wallet.</p>");
5234
        sb.append("<p>Team SmartDukaan</p>");
32822 ranu 5235
        sb.append("</body></html>");
5236
        return sb.toString();
5237
    }
5238
 
5239
 
33874 ranu 5240
    @Autowired
5241
    private FofoOpeningStockRepository fofoOpeningStockRepository;
34450 ranu 5242
    @Autowired
5243
    private SmartCartService smartCartService;
33874 ranu 5244
 
5245
    public void createOpeningStockPartyWise() throws Exception {
5246
        // Get all partner stock data
35329 ranu 5247
        Map<Integer, List<PartnerOpeningStockByTodayModel>> partnerOpeningStockByTodayInStockMap = currentInventorySnapshotRepository.getAllPartnerTodayInstock();
5248
        Map<Integer, List<PartnerOpeningStockByTodayModel>> partnerOpeningStockByTodayGrnPending = currentInventorySnapshotRepository.getAllPartnerTodayGrnPending();
5249
 
5250
        Map<Integer, List<PartnerOpeningStockByTodayModel>> partnerOpeningStockByTodayMap =
5251
                new HashMap<>();
5252
 
5253
// STEP 1: Copy in-stock data
5254
        partnerOpeningStockByTodayInStockMap.forEach((fofoId, list) ->
5255
                partnerOpeningStockByTodayMap.put(
5256
                        fofoId,
5257
                        new ArrayList<>(list)   // deep list copy
5258
                )
5259
        );
5260
 
5261
// STEP 2: Merge GRN pending using streams
5262
        partnerOpeningStockByTodayGrnPending.forEach((fofoId, grnList) -> {
5263
 
5264
            // If FOFO missing → simply insert GRN list (deep copy)
5265
            partnerOpeningStockByTodayMap
5266
                    .computeIfAbsent(fofoId, x -> new ArrayList<>())
5267
                    .addAll(
5268
                            grnList.stream()
5269
                                    .map(g -> new PartnerOpeningStockByTodayModel(
5270
                                            g.getFofoId(),
5271
                                            g.getCatalogId(),
5272
                                            g.getModelNumber(),
5273
                                            g.getOpeningQty()
5274
                                    ))
5275
                                    .collect(Collectors.toList())
5276
                    );
5277
        });
5278
 
5279
// STEP 3: Now merge duplicates per catalogId using grouping
5280
        partnerOpeningStockByTodayMap.replaceAll((fofoId, list) ->
5281
                list.stream()
5282
                        .collect(Collectors.toMap(
5283
                                PartnerOpeningStockByTodayModel::getCatalogId,
5284
                                m -> new PartnerOpeningStockByTodayModel(
5285
                                        m.getFofoId(),
5286
                                        m.getCatalogId(),
5287
                                        m.getModelNumber(),
5288
                                        m.getOpeningQty()
5289
                                ),
5290
                                // merge function: sum openingQty
5291
                                (m1, m2) -> {
5292
                                    m1.setOpeningQty(m1.getOpeningQty() + m2.getOpeningQty());
5293
                                    return m1;
5294
                                }
5295
                        ))
5296
                        .values()
5297
                        .stream()
5298
                        .collect(Collectors.toList())
5299
        );
5300
 
5301
 
34460 ranu 5302
        Map<Integer, Map<Integer, Integer>> activatedButNotBilledCatalogQtyMap = smartCartService.activatedButNotBilledCatalogQtyMap();
34502 amit.gupta 5303
        LOGGER.info("PartnerOpeningStockByTodayModel {}", partnerOpeningStockByTodayMap);
33874 ranu 5304
        for (Map.Entry<Integer, List<PartnerOpeningStockByTodayModel>> entry : partnerOpeningStockByTodayMap.entrySet()) {
5305
            int fofoId = entry.getKey();
5306
            List<PartnerOpeningStockByTodayModel> partnerStockList = entry.getValue();
34450 ranu 5307
            // Get the sold (activated-but-not-billed) quantity for this fofo and catalog
34460 ranu 5308
            Map<Integer, Integer> activatedButNotBilledQtyMap = activatedButNotBilledCatalogQtyMap.getOrDefault(fofoId, Collections.emptyMap());
33874 ranu 5309
 
34450 ranu 5310
            //  if stock is avaialble in snapshot
33874 ranu 5311
            for (PartnerOpeningStockByTodayModel partnerStock : partnerStockList) {
5312
                int catalogId = partnerStock.getCatalogId();
34450 ranu 5313
                int stockCurrentQty = partnerStock.getOpeningQty();
33874 ranu 5314
                LocalDate openingDate = partnerStock.getOpeningDate();
5315
 
34460 ranu 5316
                int soldButNotBilledQty = activatedButNotBilledQtyMap.getOrDefault(catalogId, 0);
34450 ranu 5317
 
35521 amit 5318
                if (catalogId == 1025656 && fofoId == 175140232) {
5319
                    LOGGER.info("catalogId {}", catalogId);
5320
                    LOGGER.info("fofoId {}", fofoId);
5321
                    LOGGER.info("soldButNotBilledQty {}", soldButNotBilledQty);
5322
                    LOGGER.info("stockCurrentQty {}", stockCurrentQty);
35329 ranu 5323
                }
5324
 
34450 ranu 5325
                // Subtract soldQty from partnerCurrentQty
34460 ranu 5326
                int partnerCurrentQty = Math.max(stockCurrentQty - soldButNotBilledQty, 0); // Ensure it doesn't go negative
34450 ranu 5327
 
5328
 
33874 ranu 5329
                // Check if an entry already exists in the FofoOpeningStock table
5330
                FofoOpeningStock existingStock = fofoOpeningStockRepository.findByFofoIdAndCatalogId(fofoId, catalogId);
5331
 
34162 ranu 5332
 
33874 ranu 5333
                if (existingStock != null) {
34363 ranu 5334
                    if (partnerCurrentQty < 1 && existingStock.getOpeningDate().isBefore(LocalDate.now().minusDays(5))) {
34160 tejus.loha 5335
                        fofoOpeningStockRepository.delete(existingStock);
5336
                    }
34162 ranu 5337
                    if (existingStock.getOpeningQty() < partnerCurrentQty) {
5338
                        existingStock.setOpeningQty(partnerCurrentQty);
5339
                        existingStock.setCurrentQty(partnerCurrentQty);
33874 ranu 5340
                        existingStock.setOpeningDate(openingDate);
5341
                        LOGGER.info("if condition exist {}");
34275 tejus.loha 5342
                    } else if (existingStock.getCurrentQty() >= existingStock.getOpeningQty()) {
5343
                        existingStock.setOpeningQty(existingStock.getCurrentQty());
5344
                        existingStock.setCurrentQty(partnerCurrentQty);
5345
                        existingStock.setOpeningDate(LocalDate.now());
34363 ranu 5346
                    } else if (existingStock.getOpeningDate().isBefore(LocalDate.now().minusDays(5))) {
33878 ranu 5347
                        int averageQty = Math.round((existingStock.getCurrentQty() + existingStock.getOpeningQty()) / 2.0f);
5348
 
5349
                        if (averageQty == 1 && existingStock.getOpeningQty() == 1 && existingStock.getCurrentQty() == 0) {
5350
                            // Delete the existing stock entry from the table
5351
                            fofoOpeningStockRepository.delete(existingStock);
5352
                            LOGGER.info("Deleted record with fofoId: {}, catalogId: {} because averageQty, openingQty, and currentQty meet deletion criteria", fofoId, catalogId);
5353
                        } else {
5354
                            // Update the existing stock with the new average quantity
5355
                            existingStock.setOpeningQty(averageQty);
34244 ranu 5356
                            existingStock.setCurrentQty(partnerCurrentQty);
33878 ranu 5357
                            existingStock.setOpeningDate(LocalDate.now());
34363 ranu 5358
                            LOGGER.info("Updated due to date being older than 5 days with average quantity: {}", averageQty);
33878 ranu 5359
                        }
34275 tejus.loha 5360
                    } else {
34244 ranu 5361
                        existingStock.setCurrentQty(partnerCurrentQty);
33874 ranu 5362
                    }
5363
                } else {
5364
                    LOGGER.info("else condition exist");
5365
                    FofoOpeningStock newStock = new FofoOpeningStock();
5366
                    newStock.setFofoId(fofoId);
5367
                    newStock.setCatalogId(catalogId);
34162 ranu 5368
                    newStock.setOpeningQty(partnerCurrentQty);
5369
                    newStock.setCurrentQty(partnerCurrentQty);
33874 ranu 5370
                    newStock.setOpeningDate(openingDate);
5371
                    fofoOpeningStockRepository.persist(newStock);
5372
 
5373
                }
5374
            }
34162 ranu 5375
 
5376
//            if stock is not available in snapshot but available in opening stock
34275 tejus.loha 5377
            List<FofoOpeningStock> fofoOpeningStockList = fofoOpeningStockRepository.selectAllByFofoId(fofoId);
34162 ranu 5378
 
34275 tejus.loha 5379
            for (FofoOpeningStock fofoOpeningStock : fofoOpeningStockList) {
34162 ranu 5380
 
34275 tejus.loha 5381
                if (!partnerStockList.stream().anyMatch(partnerStock -> partnerStock.getCatalogId() == fofoOpeningStock.getCatalogId())) {
34363 ranu 5382
                    if (fofoOpeningStock.getOpeningDate().isBefore(LocalDate.now().minusDays(5))) {
34275 tejus.loha 5383
                        LOGGER.info("not match stock{}", fofoOpeningStock);
5384
                        fofoOpeningStockRepository.delete(fofoOpeningStock);
5385
                    } else {
5386
                        LOGGER.info("not match stock2{}", fofoOpeningStock);
5387
                        fofoOpeningStock.setCurrentQty(0);
5388
                    }
34162 ranu 5389
 
34275 tejus.loha 5390
                }
5391
            }
34162 ranu 5392
 
33874 ranu 5393
        }
5394
    }
5395
 
5396
 
34162 ranu 5397
    @Autowired
5398
    private CategorisedCatalogRepository categorisedCatalogRepository;
5399
 
5400
    public void groupHidCatalogsByWeeks() throws ProfitMandiBusinessException, MessagingException, IOException {
5401
        List<CategorisedCatalogListModel> categorisedCatalogs = categorisedCatalogRepository.getListByStatus(CatalogMovingEnum.HID);
5402
        LocalDate currentDate = LocalDate.now();
5403
        LocalDate oneWeekAgo = currentDate.minusDays(7);
5404
        LocalDate twoWeeksAgo = currentDate.minusDays(14);
5405
        LocalDate threeWeeksAgo = currentDate.minusDays(21);
5406
 
5407
        // This Week (inclusive of the current date)
5408
        List<CategorisedCatalogListModel> thisWeekCatalogs = categorisedCatalogs.stream()
5409
                .filter(catalog -> !catalog.getStatusCreatedDate().isBefore(oneWeekAgo))
5410
                .collect(Collectors.toList());
5411
 
5412
        // Last Week (from one week ago to two weeks ago, exclusive of this week)
5413
        List<CategorisedCatalogListModel> lastWeekCatalogs = categorisedCatalogs.stream()
5414
                .filter(catalog -> catalog.getStatusCreatedDate().isBefore(oneWeekAgo) && !catalog.getStatusCreatedDate().isBefore(twoWeeksAgo))
5415
                .collect(Collectors.toList());
5416
 
5417
        // Two Weeks Ago (from two weeks ago to three weeks ago, exclusive of last week)
5418
        List<CategorisedCatalogListModel> twoWeeksAgoCatalogs = categorisedCatalogs.stream()
5419
                .filter(catalog -> catalog.getStatusCreatedDate().isBefore(twoWeeksAgo) && !catalog.getStatusCreatedDate().isBefore(threeWeeksAgo))
5420
                .collect(Collectors.toList());
5421
 
5422
        // Older than Two Weeks Ago (anything older than three weeks ago)
5423
        List<CategorisedCatalogListModel> olderCatalogs = categorisedCatalogs.stream()
5424
                .filter(catalog -> catalog.getStatusCreatedDate().isBefore(threeWeeksAgo))
5425
                .collect(Collectors.toList());
5426
 
5427
 
5428
        String subject = "Hid Catalogs";
5429
        StringBuilder sb = new StringBuilder();
5430
 
5431
        sb.append("<html><body><p>Hi Catagory Team,\n");
5432
        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;'>");
5433
 
5434
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
5435
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
5436
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
5437
        sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");
5438
        sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");
5439
        sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");
5440
        sb.append("</tr>\n");
5441
 
5442
        for (CategorisedCatalogListModel catalog : thisWeekCatalogs) {
5443
            sb.append("<tr>");
5444
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");
5445
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");
5446
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");
5447
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");
5448
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");
5449
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");
5450
 
5451
            sb.append("</tr>\n");
5452
 
5453
        }
5454
 
5455
        sb.append("</table>");
5456
 
5457
        sb.append("</br>");
5458
        sb.append("</br>");
5459
        sb.append("</br>");
5460
        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;'>");
5461
 
5462
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
5463
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
5464
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
5465
        sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");
5466
        sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");
5467
        sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");
5468
        sb.append("</tr>\n");
5469
 
5470
        for (CategorisedCatalogListModel catalog : lastWeekCatalogs) {
5471
            sb.append("<tr>");
5472
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");
5473
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");
5474
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");
5475
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");
5476
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");
5477
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");
5478
 
5479
            sb.append("</tr>\n");
5480
 
5481
        }
5482
        sb.append("</table>");
5483
 
5484
        sb.append("</br>");
5485
        sb.append("</br>");
5486
        sb.append("</br>");
5487
        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;'>");
5488
 
5489
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
5490
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
5491
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
5492
        sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");
5493
        sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");
5494
        sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");
5495
        sb.append("</tr>\n");
5496
 
5497
        for (CategorisedCatalogListModel catalog : twoWeeksAgoCatalogs) {
5498
            sb.append("<tr>");
5499
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");
5500
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");
5501
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");
5502
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");
5503
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");
5504
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");
5505
 
5506
            sb.append("</tr>\n");
5507
 
5508
        }
5509
        sb.append("</table>");
5510
 
5511
        sb.append("</br>");
5512
        sb.append("</br>");
5513
        sb.append("</br>");
5514
        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;'>");
5515
 
5516
        sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");
5517
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");
5518
        sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");
5519
        sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");
5520
        sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");
5521
        sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");
5522
        sb.append("</tr>\n");
5523
 
5524
        for (CategorisedCatalogListModel catalog : olderCatalogs) {
5525
            sb.append("<tr>");
5526
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");
5527
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");
5528
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");
5529
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");
5530
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");
5531
            sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");
5532
 
5533
            sb.append("</tr>\n");
5534
 
5535
        }
5536
        sb.append("</table>");
5537
        sb.append("</body></html>");
5538
 
36936 vikas 5539
        List<String> sendTo = Arrays.asList("sourcing@smartdukaan.com", "tarun.verma@smartdukaan.com");
34162 ranu 5540
 
5541
 
5542
        String[] email = sendTo.toArray(new String[sendTo.size()]);
5543
 
36402 amit 5544
        this.sendMailOfHtmlFormat(gmailRelaySender, email, sb.toString(), null, subject);
34162 ranu 5545
    }
5546
 
34275 tejus.loha 5547
    public void send10OrMoreOlderStockReport() throws Exception {
35094 ranu 5548
        System.out.print("testSTart");
34352 amit.gupta 5549
        purSaleService.moreThen10DaysEgedStockReport();
35094 ranu 5550
        System.out.print("testEnd");
34162 ranu 5551
 
34275 tejus.loha 5552
    }
34162 ranu 5553
 
34791 aman.kumar 5554
    public void sendUpdateMobileBrandMarketShareQuaterlyMail() throws Exception {
5555
        String subject = "Reminder: Please Update Brand-wise Market Share";
5556
 
5557
        String body = "Dear Team,\n\n" +
5558
                "This is a gentle reminder to kindly update the brand-wise market share data for the current quarter.\n\n" +
5559
                "Best regards,\n" +
5560
                "SmartDukaan Team";
5561
 
35959 amit 5562
        mailOutboxService.queueMailViaGoogle(
34791 aman.kumar 5563
                new String[]{"sm.@smartdukaan.com"},
5564
                new String[]{"tech@smartdukaan.com"},
5565
                subject,
35959 amit 5566
                body,
5567
                "ScheduledTasks.sendUpdateMobileBrandMarketShareQuaterlyMail"
34791 aman.kumar 5568
        );
5569
    }
5570
 
5571
 
36581 amit 5572
    @Scheduled(fixedRate = 1800000)
5573
    public void refreshSnapshotAgeing() {
5574
        try {
5575
            sessionFactory.getCurrentSession().createNativeQuery(
5576
                    "UPDATE inventory.currentinventorysnapshot cis " +
5577
                    "JOIN ( " +
5578
                    "    SELECT itemId, currentWarehouseId, " +
5579
                    "           MIN(rootInvoiceDate) AS oldest, " +
5580
                    "           MAX(rootInvoiceDate) AS newest " +
5581
                    "    FROM warehouse.inventoryItem " +
5582
                    "    WHERE currentQuantity > 0 AND rootInvoiceDate IS NOT NULL " +
5583
                    "    GROUP BY itemId, currentWarehouseId " +
5584
                    ") agg ON agg.itemId = cis.item_id AND agg.currentWarehouseId = cis.warehouse_id " +
5585
                    "SET cis.oldest_invoice_date = agg.oldest, " +
5586
                    "    cis.newest_invoice_date = agg.newest"
5587
            ).executeUpdate();
5588
            LOGGER.info("Snapshot ageing refreshed");
5589
        } catch (Exception e) {
5590
            LOGGER.error("Error refreshing snapshot ageing", e);
5591
        }
5592
    }
5593
 
32210 jai.hind 5594
}
33664 amit.gupta 5595
// 2284"