Subversion Repositories SmartDukaan

Rev

Rev 37151 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 37151 Rev 37156
Line 37... Line 37...
37
import org.springframework.beans.factory.annotation.Autowired;
37
import org.springframework.beans.factory.annotation.Autowired;
38
import org.springframework.beans.factory.annotation.Qualifier;
38
import org.springframework.beans.factory.annotation.Qualifier;
39
import org.springframework.cache.annotation.Cacheable;
39
import org.springframework.cache.annotation.Cacheable;
40
import org.springframework.mail.javamail.JavaMailSender;
40
import org.springframework.mail.javamail.JavaMailSender;
41
import org.springframework.stereotype.Component;
41
import org.springframework.stereotype.Component;
-
 
42
import org.springframework.transaction.annotation.Transactional;
42
 
43
 
43
import java.nio.charset.StandardCharsets;
44
import java.nio.charset.StandardCharsets;
44
import java.time.LocalDate;
45
import java.time.LocalDate;
45
import java.time.LocalDateTime;
46
import java.time.LocalDateTime;
46
import java.time.YearMonth;
47
import java.time.YearMonth;
Line 304... Line 305...
304
 
305
 
305
    }
306
    }
306
 
307
 
307
    @SuppressWarnings("unchecked")
308
    @SuppressWarnings("unchecked")
308
    @Override
309
    @Override
-
 
310
    @Transactional(rollbackFor = Throwable.class)
309
    public Map<String, Object> updateRetailerDetails(UpdateRetailerRequest updateRetailerRequest) throws
311
    public Map<String, Object> updateRetailerDetails(UpdateRetailerRequest updateRetailerRequest) throws
310
            ProfitMandiBusinessException {
312
            ProfitMandiBusinessException {
311
        Map<String, Object> map = this.getByEmailIdOrMobileNumber(updateRetailerRequest.getEmailIdOrMobileNumber());
313
        Map<String, Object> map = this.getByEmailIdOrMobileNumber(updateRetailerRequest.getEmailIdOrMobileNumber());
312
        User dtrUser = (User) map.get("user");
314
        User dtrUser = (User) map.get("user");
313
 
315
 
-
 
316
        if (updateRetailerRequest.isFofo()) {
-
 
317
            Retailer resolvedRetailer = (Retailer) map.get("retailer");
-
 
318
            if (resolvedRetailer == null) {
-
 
319
                // This save would mint a brand-new identity chain. Mandate: a partner
-
 
320
                // gets a new store code only after the old store is closed, and the
-
 
321
                // re-onboarding must reuse the partner's real email (takeover below) —
-
 
322
                // never a variant email that forks a duplicate chain.
-
 
323
                this.guardAgainstDuplicatePartnerChain(updateRetailerRequest);
-
 
324
            } else if (updateRetailerRequest.isActive()) {
-
 
325
                FofoStore existingStore = this.selectStoreOrNull(resolvedRetailer.getId());
-
 
326
                if (existingStore != null && existingStore.isClosed()) {
-
 
327
                    this.takeoverClosedStoreIdentity(existingStore, map);
-
 
328
                }
-
 
329
            }
-
 
330
        }
-
 
331
 
314
        dtrUser = this.createUser(dtrUser, updateRetailerRequest);
332
        dtrUser = this.createUser(dtrUser, updateRetailerRequest);
315
 
333
 
316
        map.put("user", dtrUser);
334
        map.put("user", dtrUser);
317
        List<UserRole> userRoles = (List<UserRole>) map.get("userRoles");
335
        List<UserRole> userRoles = (List<UserRole>) map.get("userRoles");
318
        Role roleUser = roleRepository.selectByName(RoleType.USER.toString());
336
        Role roleUser = roleRepository.selectByName(RoleType.USER.toString());
Line 320... Line 338...
320
        Retailer retailer = (Retailer) map.get("retailer");
338
        Retailer retailer = (Retailer) map.get("retailer");
321
        retailer = this.updateRetailer(dtrUser, retailer, updateRetailerRequest);
339
        retailer = this.updateRetailer(dtrUser, retailer, updateRetailerRequest);
322
 
340
 
323
        map.put("retailer", retailer);
341
        map.put("retailer", retailer);
324
 
342
 
325
        // Ensure UserAccount links new dtr user to retailer (handles case where
343
        // Ensure the dtr login's bridge rows point at the current identity. Repairs
326
        // dtr.user was deleted and re-created with a new ID)
344
        // recreated logins and repoints the login after a closed-store takeover.
-
 
345
        userAccountRepository.upsert(dtrUser.getId(), AccountType.saholic, retailer.getId());
327
        try {
346
        try {
328
            userAccountRepository.selectSaholicByUserId(dtrUser.getId());
347
            com.spice.profitmandi.dao.entity.user.User identity = userUserRepository.selectById(retailer.getId());
329
        } catch (ProfitMandiBusinessException e) {
-
 
330
            try {
-
 
331
                UserAccount ua = new UserAccount();
-
 
332
                ua.setAccountKey(retailer.getId());
348
            if (identity.getActiveCartId() > 0) {
333
                ua.setUserId(dtrUser.getId());
-
 
334
                ua.setType(AccountType.saholic);
-
 
335
                userAccountRepository.persist(ua);
-
 
336
            } catch (Exception ex) {
-
 
337
                LOGGER.error("Error creating saholic UserAccount for userId: {}", dtrUser.getId(), ex);
349
                userAccountRepository.upsert(dtrUser.getId(), AccountType.cartId, identity.getActiveCartId());
338
            }
350
            }
-
 
351
        } catch (ProfitMandiBusinessException e) {
-
 
352
            LOGGER.error("Error ensuring cartId UserAccount for userId: {}", dtrUser.getId(), e);
339
        }
353
        }
340
 
354
 
341
        List<String> retailerBlockBrands = retailerBlockBrandsRepository.selectAllByRetailer(retailer.getId()).stream().map(x -> x.getBlockBrands()).collect(Collectors.toList());
355
        List<String> retailerBlockBrands = retailerBlockBrandsRepository.selectAllByRetailer(retailer.getId()).stream().map(x -> x.getBlockBrands()).collect(Collectors.toList());
342
 
356
 
343
        LOGGER.info("retailerBlockBrands" + retailerBlockBrands);
357
        LOGGER.info("retailerBlockBrands" + retailerBlockBrands);
Line 408... Line 422...
408
 
422
 
409
        return map;
423
        return map;
410
 
424
 
411
    }
425
    }
412
 
426
 
-
 
427
    private FofoStore selectStoreOrNull(int retailerId) {
-
 
428
        try {
-
 
429
            return fofoStoreRepository.selectByRetailerId(retailerId);
-
 
430
        } catch (ProfitMandiBusinessException e) {
-
 
431
            return null;
-
 
432
        }
-
 
433
    }
-
 
434
 
-
 
435
    private void guardAgainstDuplicatePartnerChain(UpdateRetailerRequest updateRetailerRequest)
-
 
436
            throws ProfitMandiBusinessException {
-
 
437
        User byMobile = null;
-
 
438
        try {
-
 
439
            byMobile = userRepository.selectByMobileNumber(updateRetailerRequest.getUserMobileNumber());
-
 
440
        } catch (ProfitMandiBusinessException e) {
-
 
441
            // no dtr user with this mobile
-
 
442
        }
-
 
443
        if (byMobile != null) {
-
 
444
            Integer accountKey = userAccountRepository.selectSaholicAccountKeySafe(byMobile.getId());
-
 
445
            FofoStore store = accountKey != null ? this.selectStoreOrNull(accountKey) : null;
-
 
446
            if (store != null) {
-
 
447
                if (!store.isClosed()) {
-
 
448
                    throw new ProfitMandiBusinessException("Open store exists", store.getCode(),
-
 
449
                            "Partner mobile " + updateRetailerRequest.getUserMobileNumber()
-
 
450
                                    + " already owns open store " + store.getCode()
-
 
451
                                    + ". Close it first, or use email-change to keep the same code.");
-
 
452
                }
-
 
453
                throw new ProfitMandiBusinessException("Closed store exists", store.getCode(),
-
 
454
                        "Old store " + store.getCode() + " is closed. Re-onboard using the partner's existing email "
-
 
455
                                + byMobile.getEmailId() + " and a new code will be issued automatically.");
-
 
456
            }
-
 
457
        }
-
 
458
        if (!updateRetailerRequest.isAllowAdditionalOutlet()) {
-
 
459
            List<FofoStore> openGstStores = fofoStoreRepository.selectAllOpenByGstNumber(updateRetailerRequest.getGstNumber());
-
 
460
            if (!openGstStores.isEmpty()) {
-
 
461
                String codes = openGstStores.stream().map(FofoStore::getCode).collect(Collectors.joining(", "));
-
 
462
                throw new ProfitMandiBusinessException("Open store exists for GST", codes,
-
 
463
                        "GST " + updateRetailerRequest.getGstNumber() + " already has open store(s) " + codes
-
 
464
                                + ". Close the old store first, or tick 'Additional outlet for same GST' if this is genuinely a new outlet.");
-
 
465
            }
-
 
466
        }
-
 
467
    }
-
 
468
 
-
 
469
    private void takeoverClosedStoreIdentity(FofoStore oldStore, Map<String, Object> map) {
-
 
470
        // Mandate: closed stores are never reopened. Re-onboarding with the partner's
-
 
471
        // real contacts issues a fresh code on the same dtr login: free the old
-
 
472
        // identity's email so the new user.user can take it over, then drop the old
-
 
473
        // chain from the resolution map so the save proceeds as a fresh onboarding.
-
 
474
        try {
-
 
475
            com.spice.profitmandi.dao.entity.user.User oldIdentity = userUserRepository.selectById(oldStore.getId());
-
 
476
            String tombstone = "closed." + oldStore.getId() + "." + oldIdentity.getEmailId();
-
 
477
            if (tombstone.length() > 128) {
-
 
478
                tombstone = tombstone.substring(0, 128);
-
 
479
            }
-
 
480
            oldIdentity.setEmailId(tombstone);
-
 
481
        } catch (ProfitMandiBusinessException e) {
-
 
482
            LOGGER.error("Takeover: identity not found for closed store {}", oldStore.getId(), e);
-
 
483
        }
-
 
484
        LOGGER.info("Takeover: closed store {} ({}) — issuing new code on the same login", oldStore.getCode(), oldStore.getId());
-
 
485
        map.remove("retailer");
-
 
486
        map.remove("retailerAddress");
-
 
487
        map.remove("shops");
-
 
488
        map.remove("fofoStore");
-
 
489
    }
-
 
490
 
413
    private void createDefaultPaymentOption(int fofoId) {
491
    private void createDefaultPaymentOption(int fofoId) {
414
        List<Integer> paymentOptionIds = fofoPartnerPaymentOptionRepository.selectPaymentOptionIdsByFofoId(fofoId);
492
        List<Integer> paymentOptionIds = fofoPartnerPaymentOptionRepository.selectPaymentOptionIdsByFofoId(fofoId);
415
        if (paymentOptionIds.isEmpty()) {
493
        if (paymentOptionIds.isEmpty()) {
416
            PaymentOption paymentOption = null;
494
            PaymentOption paymentOption = null;
417
            try {
495
            try {
Line 492... Line 570...
492
            saholicUser.setName(retailerName);
570
            saholicUser.setName(retailerName);
493
            saholicUser.setActiveCartId(cart.getId());
571
            saholicUser.setActiveCartId(cart.getId());
494
            saholicUser.setCreateTimestamp(LocalDateTime.now());
572
            saholicUser.setCreateTimestamp(LocalDateTime.now());
495
            userUserRepository.persist(saholicUser);
573
            userUserRepository.persist(saholicUser);
496
 
574
 
497
            UserAccount ua = new UserAccount();
-
 
498
            ua.setAccountKey(saholicUser.getId());
575
            userAccountRepository.upsert(user.getId(), AccountType.saholic, saholicUser.getId());
499
            ua.setUserId(user.getId());
-
 
500
            ua.setType(AccountType.saholic);
-
 
501
            userAccountRepository.persist(ua);
-
 
502
 
-
 
503
            UserAccount ua2 = new UserAccount();
-
 
504
            ua2.setAccountKey(saholicUser.getActiveCartId());
576
            userAccountRepository.upsert(user.getId(), AccountType.cartId, saholicUser.getActiveCartId());
505
            ua2.setUserId(user.getId());
-
 
506
            ua2.setType(AccountType.cartId);
-
 
507
            userAccountRepository.persist(ua2);
-
 
508
            LOGGER.info("created....");
577
            LOGGER.info("created....");
509
        }
578
        }
510
        return saholicUser.getId();
579
        return saholicUser.getId();
511
    }
580
    }
512
 
581