Subversion Repositories SmartDukaan

Rev

Rev 37143 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 37143 Rev 37302
Line 25... Line 25...
25
import com.spice.profitmandi.dao.enumuration.transaction.TransactionApprovalStatus;
25
import com.spice.profitmandi.dao.enumuration.transaction.TransactionApprovalStatus;
26
import com.spice.profitmandi.dao.model.CartItem;
26
import com.spice.profitmandi.dao.model.CartItem;
27
import com.spice.profitmandi.dao.model.UserCart;
27
import com.spice.profitmandi.dao.model.UserCart;
28
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
28
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
29
import com.spice.profitmandi.dao.repository.catalog.BidRepository;
29
import com.spice.profitmandi.dao.repository.catalog.BidRepository;
-
 
30
import com.spice.profitmandi.dao.entity.catalog.Category;
-
 
31
import com.spice.profitmandi.dao.entity.user.CartLine;
-
 
32
import com.spice.profitmandi.dao.repository.catalog.CategoryRepository;
30
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
33
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
-
 
34
import com.spice.profitmandi.dao.repository.user.CartLineRepository;
31
import com.spice.profitmandi.dao.repository.catalog.LiquidationRepository;
35
import com.spice.profitmandi.dao.repository.catalog.LiquidationRepository;
32
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
36
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
33
import com.spice.profitmandi.dao.repository.cs.CsService;
37
import com.spice.profitmandi.dao.repository.cs.CsService;
34
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
38
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
35
import com.spice.profitmandi.dao.repository.dtr.UserRepository;
39
import com.spice.profitmandi.dao.repository.dtr.UserRepository;
Line 101... Line 105...
101
    @Autowired
105
    @Autowired
102
    private BidService bidService;
106
    private BidService bidService;
103
    @Autowired
107
    @Autowired
104
    ItemRepository itemRepository;
108
    ItemRepository itemRepository;
105
    @Autowired
109
    @Autowired
-
 
110
    CategoryRepository categoryRepository;
-
 
111
    @Autowired
-
 
112
    CartLineRepository cartLineRepository;
-
 
113
    @Autowired
106
    private BrandsService brandsService;
114
    private BrandsService brandsService;
107
    @Autowired
115
    @Autowired
108
    private LoanTransactionRepository loanTransactionRepository;
116
    private LoanTransactionRepository loanTransactionRepository;
109
 
117
 
110
    @Autowired
118
    @Autowired
Line 266... Line 274...
266
            if (enforceCombo) {
274
            if (enforceCombo) {
267
                comboService.validateCombo(userCart);
275
                comboService.validateCombo(userCart);
268
            }
276
            }
269
            // createtransactionInternally set the value in transaction table
277
            // createtransactionInternally set the value in transaction table
270
 
278
 
-
 
279
            // Refurbished (margin scheme) lines are invoiced on their own RF- series, so they must not share a
-
 
280
            // transaction with regular lines - one billing group per invoice. Everything above (pricing, combo,
-
 
281
            // credit availability) still validates the order as a whole; only the transaction is raised per group.
-
 
282
            List<List<CartLine>> cartLineGroups = this.splitCartLinesByMarginScheme(userCart.getCartId());
-
 
283
            // A loan settles against an invoice, so each group needs its own. Wallet is consumed in group order,
-
 
284
            // so only what a group cannot fund from the balance left to it is borrowed.
-
 
285
            List<Integer> groupLoanIds = new ArrayList<>();
-
 
286
            double remainingWalletAmount = walletAmount;
-
 
287
            for (List<CartLine> groupCartLines : cartLineGroups) {
-
 
288
                double groupPayableAmount = this.getPayableAmount(groupCartLines);
-
 
289
                double walletUsedByGroup = Math.min(remainingWalletAmount, groupPayableAmount);
271
            double creditAmountRequired = totalPayableAmount - walletAmount;
290
                double creditAmountRequired = groupPayableAmount - walletUsedByGroup;
-
 
291
                remainingWalletAmount -= walletUsedByGroup;
272
            int loanId = 0;
292
                int loanId = 0;
273
            try {
293
                try {
274
                if (creditAmountRequired > ProfitMandiConstants.MAX_NEGATIVE_WALLET_VALUE) {
294
                    if (creditAmountRequired > ProfitMandiConstants.MAX_NEGATIVE_WALLET_VALUE) {
275
                    LOGGER.info("Creating new loan for: {}",userCart.getUserId());
295
                        LOGGER.info("Creating new loan for: {}",userCart.getUserId());
276
                    BlockLoanIdSanctionId loan = sdCreditService.createSDDirectOrder(userCart.getUserId(), totalPayableAmount, 0);
296
                        BlockLoanIdSanctionId loan = sdCreditService.createSDDirectOrder(userCart.getUserId(), groupPayableAmount, 0);
277
                    loanId = loan.getLoanId();
297
                        loanId = loan.getLoanId();
278
                }
298
                    }
279
            } catch (Exception exception){
299
                } catch (Exception exception){
280
                if (type.equals(ProfitMandiConstants.PO_TYPE.AUTO)) {
300
                    if (type.equals(ProfitMandiConstants.PO_TYPE.AUTO)) {
281
                    finalBidStatus = bidService.sendMailToRBM(netAmountInHand, totalPayableAmount, fofoId);
301
                        finalBidStatus = bidService.sendMailToRBM(netAmountInHand, totalPayableAmount, fofoId);
282
                    LOGGER.info("Skipping order due to insufficient balance for id - "+ fofoId+ " Cancelling the BID");
302
                        LOGGER.info("Skipping order due to insufficient balance for id - "+ fofoId+ " Cancelling the BID");
283
                    //throw new ProfitMandiBusinessException("Skipping order unable to create load for id - ", fofoId, " ,Sending mail to RBM");
303
                        //throw new ProfitMandiBusinessException("Skipping order unable to create load for id - ", fofoId, " ,Sending mail to RBM");
-
 
304
                    }
284
                }
305
                }
-
 
306
                groupLoanIds.add(loanId);
285
            }
307
            }
286
 
308
 
287
            LOGGER.info("finalBidStatus: {}",finalBidStatus);
309
            LOGGER.info("finalBidStatus: {}",finalBidStatus);
288
            if (finalBidStatus.equals(ProfitMandiConstants.BID_ENUM.CLOSED)) {
310
            if (finalBidStatus.equals(ProfitMandiConstants.BID_ENUM.CLOSED)) {
289
                // Block all PO creation while a first PO is pending approval for this partner
311
                // Block all PO creation while a first PO is pending approval for this partner
Line 355... Line 377...
355
 
377
 
356
                        }
378
                        }
357
                    }
379
                    }
358
                }
380
                }
359
 
381
 
360
                LOGGER.info("totalPayableAmount - {}", totalPayableAmount);
-
 
361
                int transactionId = transactionService.createTransactionInternally(userCart, totalPayableAmount, 0);
-
 
362
                //Set here created by
-
 
363
                Transaction transaction = transactionRepository.selectById(transactionId);
-
 
364
                transaction.setCreatedBy(creatorId);
-
 
365
                LOGGER.info("transaction created by {}", transaction.getCreatedBy());
-
 
366
                commonPaymentService.payThroughWallet(transactionId);
-
 
367
 
-
 
368
                // First PO always requires approval
382
                // First PO always requires approval
369
                if (isFirstPO) {
383
                if (isFirstPO) {
370
                    approvalRequired = true;
384
                    approvalRequired = true;
371
                }
385
                }
372
 
386
 
-
 
387
                for (int groupIndex = 0; groupIndex < cartLineGroups.size(); groupIndex++) {
-
 
388
                    List<CartLine> groupCartLines = cartLineGroups.get(groupIndex);
-
 
389
                    int loanId = groupLoanIds.get(groupIndex);
-
 
390
                    double groupPayableAmount = this.getPayableAmount(groupCartLines);
-
 
391
 
-
 
392
                    LOGGER.info("totalPayableAmount - {}", groupPayableAmount);
-
 
393
                    int transactionId = transactionService.createTransactionForCartLines(userCart, groupCartLines, groupPayableAmount, 0);
-
 
394
                    //Set here created by
-
 
395
                    Transaction transaction = transactionRepository.selectById(transactionId);
-
 
396
                    transaction.setCreatedBy(creatorId);
-
 
397
                    LOGGER.info("transaction created by {}", transaction.getCreatedBy());
-
 
398
                    commonPaymentService.payThroughWallet(transactionId);
-
 
399
 
373
                if (approvalRequired) {
400
                    if (approvalRequired) {
374
                    this.createApproval(transactionId, isFirstPO);
401
                        this.createApproval(transactionId, isFirstPO);
375
                    if (loanId > 0) {
402
                        if (loanId > 0) {
376
                        LoanTransaction loanTransaction = new LoanTransaction();
403
                            LoanTransaction loanTransaction = new LoanTransaction();
377
                        loanTransaction.setLoanId(loanId);
404
                            loanTransaction.setLoanId(loanId);
378
                        loanTransaction.setTransactionId(transactionId);
405
                            loanTransaction.setTransactionId(transactionId);
379
                        loanTransactionRepository.persist(loanTransaction);
406
                            loanTransactionRepository.persist(loanTransaction);
-
 
407
                        }
-
 
408
                    } else {
-
 
409
                        transactionService.processTransaction(transactionId, loanId);
380
                    }
410
                    }
381
                } else {
-
 
382
                    transactionService.processTransaction(transactionId, loanId);
-
 
383
                }
-
 
384
 
411
 
385
                // Send approval email and track timeline for first PO
412
                    // Send approval email and track timeline for first PO
386
                if (isFirstPO) {
413
                    if (isFirstPO) {
387
                    try {
414
                        try {
388
                        sendFirstPOApprovalEmail(fofoStore, transactionId, totalPayableAmount, creatorId);
415
                            sendFirstPOApprovalEmail(fofoStore, transactionId, groupPayableAmount, creatorId);
389
                    } catch (Exception e) {
416
                        } catch (Exception e) {
390
                        LOGGER.error("Failed to send first PO approval email for fofoId: " + fofoId, e);
417
                            LOGGER.error("Failed to send first PO approval email for fofoId: " + fofoId, e);
391
                    }
418
                        }
392
                    // Track PO_CREATION on timeline for first PO (direct call like BILLING — bypasses BLOCKER_MAP
419
                        // Track PO_CREATION on timeline for first PO (direct call like BILLING — bypasses BLOCKER_MAP
393
                    // since the PO is actually being created, the timeline must record it)
420
                        // since the PO is actually being created, the timeline must record it)
394
                    try {
421
                        try {
395
                        if (fofoStore != null && fofoStore.getCode() != null) {
422
                            if (fofoStore != null && fofoStore.getCode() != null) {
396
                            com.spice.profitmandi.dao.entity.fofo.PartnerOnBoardingPanel pob =
423
                                com.spice.profitmandi.dao.entity.fofo.PartnerOnBoardingPanel pob =
397
                                    partnerOnBoardingPanelRepository.selectByCode(fofoStore.getCode());
424
                                        partnerOnBoardingPanelRepository.selectByCode(fofoStore.getCode());
398
                            if (pob != null) {
425
                                if (pob != null) {
399
                                storeTimelineTatService.createStoreTimelinetb(pob.getId(), StoreTimeline.PO_CREATION);
426
                                    storeTimelineTatService.createStoreTimelinetb(pob.getId(), StoreTimeline.PO_CREATION);
-
 
427
                                }
400
                            }
428
                            }
-
 
429
                        } catch (Exception e) {
-
 
430
                            LOGGER.error("Failed to track PO_CREATION timeline for fofoId: " + fofoId, e);
401
                        }
431
                        }
402
                    } catch (Exception e) {
-
 
403
                        LOGGER.error("Failed to track PO_CREATION timeline for fofoId: " + fofoId, e);
-
 
404
                    }
432
                    }
405
                }
433
                }
406
            }
434
            }
407
 
435
 
408
        }
436
        }
Line 419... Line 447...
419
            LOGGER.warn("Combo-enforce gate: could not resolve positions for creator {} - {}", creatorId, e.getMessage());
447
            LOGGER.warn("Combo-enforce gate: could not resolve positions for creator {} - {}", creatorId, e.getMessage());
420
            return false;
448
            return false;
421
        }
449
        }
422
    }
450
    }
423
 
451
 
-
 
452
    /**
-
 
453
     * Splits the cart into billing groups: regular lines and margin-scheme (refurbished) lines. Returns one
-
 
454
     * group when the cart is homogeneous - which is the common case - so a single-kind bulk order behaves
-
 
455
     * exactly as it did before. Lines whose item or category cannot be resolved stay with the regular group.
-
 
456
     */
-
 
457
    private List<List<CartLine>> splitCartLinesByMarginScheme(int cartId) throws ProfitMandiBusinessException {
-
 
458
        List<CartLine> cartLines = cartLineRepository.selectAllByCart(cartId);
-
 
459
        Set<Integer> itemIds = cartLines.stream().map(CartLine::getItemId).collect(Collectors.toSet());
-
 
460
        Map<Integer, Item> itemMap = itemRepository.selectByIds(itemIds).stream()
-
 
461
                .collect(Collectors.toMap(Item::getId, x -> x));
-
 
462
        List<Integer> categoryIds = itemMap.values().stream().map(Item::getCategoryId).distinct().collect(Collectors.toList());
-
 
463
        Map<Integer, Category> categoryMap = categoryRepository.selectByIds(categoryIds).stream()
-
 
464
                .collect(Collectors.toMap(Category::getId, x -> x));
-
 
465
 
-
 
466
        List<CartLine> regularCartLines = new ArrayList<>();
-
 
467
        List<CartLine> marginSchemeCartLines = new ArrayList<>();
-
 
468
        for (CartLine cartLine : cartLines) {
-
 
469
            Item item = itemMap.get(cartLine.getItemId());
-
 
470
            Category category = (item == null) ? null : categoryMap.get(item.getCategoryId());
-
 
471
            if (category != null && category.isMarginOnly()) {
-
 
472
                marginSchemeCartLines.add(cartLine);
-
 
473
            } else {
-
 
474
                regularCartLines.add(cartLine);
-
 
475
            }
-
 
476
        }
-
 
477
 
-
 
478
        List<List<CartLine>> cartLineGroups = new ArrayList<>();
-
 
479
        if (!regularCartLines.isEmpty()) {
-
 
480
            cartLineGroups.add(regularCartLines);
-
 
481
        }
-
 
482
        if (!marginSchemeCartLines.isEmpty()) {
-
 
483
            cartLineGroups.add(marginSchemeCartLines);
-
 
484
        }
-
 
485
        return cartLineGroups;
-
 
486
    }
-
 
487
 
-
 
488
    /**
-
 
489
     * Cart value of a billing group, matching the rule createTransactionForWarehouse validates against - the
-
 
490
     * 0.01 carry bag is excluded - so the amount passed in always reconciles with the lines it is passed with.
-
 
491
     */
-
 
492
    private double getPayableAmount(List<CartLine> cartLines) {
-
 
493
        BigDecimal payableAmount = new BigDecimal(0);
-
 
494
        for (CartLine cartLine : cartLines) {
-
 
495
            if (cartLine.getItemId() == ProfitMandiConstants.ITEM_CARRY_BAG
-
 
496
                    && Utils.compareDouble(cartLine.getActualPrice(), 0.01) == 0) {
-
 
497
                continue;
-
 
498
            }
-
 
499
            payableAmount = payableAmount.add(BigDecimal.valueOf(cartLine.getActualPrice())
-
 
500
                    .multiply(BigDecimal.valueOf(cartLine.getQuantity())));
-
 
501
        }
-
 
502
        return payableAmount.doubleValue();
-
 
503
    }
-
 
504
 
424
    public void createApproval(int transactionId, boolean firstPo) {
505
    public void createApproval(int transactionId, boolean firstPo) {
425
        TransactionApproval transactionApproval = new TransactionApproval();
506
        TransactionApproval transactionApproval = new TransactionApproval();
426
        transactionApproval.setId(transactionId);
507
        transactionApproval.setId(transactionId);
427
        transactionApproval.setStatus(TransactionApprovalStatus.PENDING);
508
        transactionApproval.setStatus(TransactionApprovalStatus.PENDING);
428
        transactionApproval.setFirstPo(firstPo);
509
        transactionApproval.setFirstPo(firstPo);