Subversion Repositories SmartDukaan

Rev

Rev 37706 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
26522 amit.gupta 1
package com.spice.profitmandi.dao.cart;
2
 
28653 amit.gupta 3
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
29261 amit.gupta 4
import com.spice.profitmandi.common.model.ProfitMandiConstants;
37792 amit 5
import org.springframework.beans.BeanUtils;
26522 amit.gupta 6
import com.spice.profitmandi.dao.entity.catalog.Item;
7
import com.spice.profitmandi.dao.entity.catalog.TagListing;
29327 tejbeer 8
import com.spice.profitmandi.dao.entity.cs.PartnerRegion;
9
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
35170 vikas 10
import com.spice.profitmandi.dao.entity.fofo.PartnerType;
32493 amit.gupta 11
import com.spice.profitmandi.dao.entity.inventory.SaholicCISTable;
26522 amit.gupta 12
import com.spice.profitmandi.dao.entity.user.Cart;
28166 tejbeer 13
import com.spice.profitmandi.dao.entity.user.CartLine;
26522 amit.gupta 14
import com.spice.profitmandi.dao.entity.user.User;
33172 tejus.loha 15
import com.spice.profitmandi.dao.model.*;
29327 tejbeer 16
import com.spice.profitmandi.dao.repository.catalog.FocusedModelRepository;
26522 amit.gupta 17
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
37640 amit 18
import com.spice.profitmandi.dao.repository.catalog.CatalogRepository;
26522 amit.gupta 19
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
29327 tejbeer 20
import com.spice.profitmandi.dao.repository.cs.PartnerRegionRepository;
26522 amit.gupta 21
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
22
import com.spice.profitmandi.dao.repository.fofo.CurrentInventorySnapshotRepository;
35170 vikas 23
import com.spice.profitmandi.dao.repository.fofo.PartnerTypeChangeService;
32493 amit.gupta 24
import com.spice.profitmandi.dao.repository.inventory.SaholicCISTableRepository;
29327 tejbeer 25
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
28166 tejbeer 26
import com.spice.profitmandi.dao.repository.user.CartLineRepository;
26522 amit.gupta 27
import com.spice.profitmandi.dao.repository.user.CartRepository;
28
import com.spice.profitmandi.dao.repository.user.UserRepository;
32493 amit.gupta 29
import com.spice.profitmandi.dao.repository.warehouse.BrandRegionMappingRepository;
29327 tejbeer 30
import com.spice.profitmandi.service.NotificationService;
37143 amit 31
import com.spice.profitmandi.service.catalog.BrandsService;
29327 tejbeer 32
import com.spice.profitmandi.service.inventory.FocusedShortageModel;
28653 amit.gupta 33
import com.spice.profitmandi.service.inventory.SaholicInventoryService;
35140 ranu 34
import com.spice.profitmandi.service.inventory.WarehouseIntransitDataModel;
29327 tejbeer 35
import com.spice.profitmandi.service.transaction.TransactionService;
32493 amit.gupta 36
import org.apache.logging.log4j.LogManager;
37
import org.apache.logging.log4j.Logger;
38
import org.springframework.beans.factory.annotation.Autowired;
39
import org.springframework.stereotype.Component;
26522 amit.gupta 40
 
35170 vikas 41
import java.time.LocalDate;
32493 amit.gupta 42
import java.time.LocalDateTime;
43
import java.util.*;
44
import java.util.Map.Entry;
45
import java.util.stream.Collectors;
46
 
28170 tejbeer 47
@Component
26522 amit.gupta 48
public class CartServiceImpl implements CartService {
49
 
31773 amit.gupta 50
    private static final Set<Integer> tagIds = new HashSet<>(Arrays.asList(4));
26522 amit.gupta 51
 
37792 amit 52
    private static final float CARRY_BAG_MIN_PHONE_PRICE = 12000f;
53
    private static final float CARRY_BAG_FLAT_PRICE = 1f;
54
 
31773 amit.gupta 55
    private static final Logger logger = LogManager.getLogger(CartServiceImpl.class);
28653 amit.gupta 56
 
31773 amit.gupta 57
    private static final Map<Integer, List<Integer>> focusedModelVariantMap = new HashMap<>();
29404 tejbeer 58
 
31773 amit.gupta 59
    @Autowired
60
    CartRepository cartRepository;
26522 amit.gupta 61
 
31773 amit.gupta 62
    @Autowired
63
    CartLineRepository cartLineRepository;
26522 amit.gupta 64
 
31773 amit.gupta 65
    @Autowired
66
    FofoStoreRepository fofoStoreRepository;
26522 amit.gupta 67
 
31773 amit.gupta 68
    @Autowired
69
    TagListingRepository tagListingRepository;
26522 amit.gupta 70
 
31773 amit.gupta 71
    @Autowired
72
    SaholicInventoryService saholicInventoryService;
26522 amit.gupta 73
 
31773 amit.gupta 74
    @Autowired
75
    UserRepository saholicUserRepository;
26522 amit.gupta 76
 
31773 amit.gupta 77
    @Autowired
78
    ItemRepository itemRepository;
28170 tejbeer 79
 
37283 amit 80
    @Autowired
37640 amit 81
    CatalogRepository catalogRepository;
26522 amit.gupta 82
 
37283 amit 83
 
31773 amit.gupta 84
    @Autowired
85
    CurrentInventorySnapshotRepository currentInventorySnapshotRepository;
29327 tejbeer 86
 
31773 amit.gupta 87
    @Autowired
88
    private FocusedModelRepository focusedModelRepository;
29327 tejbeer 89
 
31773 amit.gupta 90
    @Autowired
91
    private PartnerRegionRepository partnerRegionRepository;
29327 tejbeer 92
 
31773 amit.gupta 93
    @Autowired
94
    private TransactionService transactionService;
29327 tejbeer 95
 
31773 amit.gupta 96
    @Autowired
37143 amit 97
    private BrandsService brandsService;
29327 tejbeer 98
 
31773 amit.gupta 99
    @Autowired
100
    private OrderRepository orderRepository;
29327 tejbeer 101
 
31773 amit.gupta 102
    @Autowired
103
    private NotificationService notificationService;
104
    @Autowired
105
    private SaholicCISTableRepository saholicCISTableRepository;
29327 tejbeer 106
 
31773 amit.gupta 107
    @Autowired
108
    private BrandRegionMappingRepository brandRegionMappingRepository;
26522 amit.gupta 109
 
35170 vikas 110
    @Autowired
111
    private PartnerTypeChangeService partnerTypeChangeService;
112
 
31773 amit.gupta 113
    @Override
114
    // Unused method
115
    public CartModel addToCart(int cartId, int itemId, int quantity, float sellingPrice) {
116
        CartLine cartItem = cartLineRepository.selectByCartItem(cartId, itemId);
117
        if (cartItem == null) {
118
            this.createCartItem(cartId, itemId, quantity, sellingPrice);
119
        } else {
120
            cartItem.setQuantity(quantity);
121
            cartItem.setActualPrice(sellingPrice);
122
        }
123
        return null;
124
    }
26522 amit.gupta 125
 
31773 amit.gupta 126
    private void createCartItem(int cartId, int itemId, int quantity, float sellingPrice) {
37706 amit 127
        // Cart row first, then lines -- see CartRepository.selectByIdForUpdate.
128
        cartRepository.selectByIdForUpdate(cartId);
31773 amit.gupta 129
        CartLine cartLine = new CartLine();
130
        cartLine.setActualPrice(sellingPrice);
131
        cartLine.setCartId(cartId);
132
        cartLine.setQuantity(quantity);
133
        // TODO: Estmiate Logic
134
        cartLine.setEstimate(2);
135
        cartLineRepository.persist(cartLine);
26522 amit.gupta 136
 
31773 amit.gupta 137
    }
26522 amit.gupta 138
 
31773 amit.gupta 139
    @Override
140
    public boolean clearCart(int cartId) throws ProfitMandiBusinessException {
37706 amit 141
        // Cart row first, then lines -- see CartRepository.selectByIdForUpdate.
142
        cartRepository.selectByIdForUpdate(cartId);
31773 amit.gupta 143
        List<CartLine> cartLines = cartLineRepository.selectAllByCart(cartId);
144
        cartLines.stream().forEach(cartLine -> cartLineRepository.delete(cartLine));
35947 amit 145
        Cart cart = cartRepository.selectById(cartId);
26522 amit.gupta 146
 
31773 amit.gupta 147
        cart.setUpdateTimestamp(LocalDateTime.now());
148
        cart.setCheckoutTimestamp(null);
149
        cart.setTotalPrice(0);
150
        cart.setWalletAmount(0);
151
        return true;
152
    }
26522 amit.gupta 153
 
31773 amit.gupta 154
    @Override
155
    public CartModel getCart(int cartId) {
156
        // TODO Auto-generated method stub
157
        return null;
158
    }
26522 amit.gupta 159
 
31773 amit.gupta 160
    // As of now it only works for Fofo Partners need to be refactored later
161
    private Map<Integer, Integer> getAvailabilityMap(User user, Set<Integer> itemIds) {
162
        Map<Integer, Integer> itemAvailabilityMap = new HashMap<>();
163
        List<TagListing> tags = tagListingRepository.selectByItemIdsAndTagIds(itemIds, tagIds);
37640 amit 164
        // Hot deals are brand-driven: catalog.brand = 'Hot Deal'. No date window.
165
        Set<Integer> hotDealCatalogIds = catalogRepository
166
                .selectCatalogIdsByBrand(ProfitMandiConstants.HOT_DEAL_BRAND);
37283 amit 167
        Map<Integer, Integer> itemCatalogMap = new HashMap<>();
168
        try {
169
            for (Item item : itemRepository.selectByIds(itemIds)) {
170
                itemCatalogMap.put(item.getId(), item.getCatalogItemId());
171
            }
172
        } catch (ProfitMandiBusinessException e) {
173
            logger.error("Could not load items for availability map", e);
174
        }
31773 amit.gupta 175
        tags.stream().forEach(tagListing -> {
37283 amit 176
            if (!tagListing.isActive()
177
                    || hotDealCatalogIds.contains(itemCatalogMap.get(tagListing.getItemId()))) {
31773 amit.gupta 178
                // show actual values here
179
            } else {
32585 amit.gupta 180
                itemAvailabilityMap.put(tagListing.getItemId(), 400);
31773 amit.gupta 181
            }
182
        });
183
        return itemAvailabilityMap;
184
    }
26522 amit.gupta 185
 
31773 amit.gupta 186
    // As of now it only works for Fofo Partners need to be refactored later
33244 ranu 187
    private Map<Integer, Integer> getMinBuyQtyMap(User user, Set<Integer> itemIds) throws ProfitMandiBusinessException {
31773 amit.gupta 188
        List<Item> items = itemRepository.selectByIds(itemIds);
189
        return items.stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getCategoryId() == 10020 ? 1 : 10));
190
    }
26522 amit.gupta 191
 
31773 amit.gupta 192
    // As of now it only works for Fofo Partners need to be refactored later
193
    private Map<Integer, Float> getPriceMap(User user, Set<Integer> itemIds) {
194
        List<TagListing> tags = tagListingRepository.selectByItemIdsAndTagIds(itemIds, tagIds);
195
        return tags.stream().collect(Collectors.toMap(x -> x.getItemId(), x -> x.getSellingPrice()));
28653 amit.gupta 196
 
31773 amit.gupta 197
    }
28653 amit.gupta 198
 
31773 amit.gupta 199
    @Override
200
    public CartResponse getCartValidation(int cartId) throws ProfitMandiBusinessException {
37706 amit 201
        // This method WRITES (cart.totalPrice, cart_line qty/price, line deletes) despite its
202
        // name, so it is a mutating path: cart row first, then lines.
203
        // See CartRepository.selectByIdForUpdate.
204
        cartRepository.selectByIdForUpdate(cartId);
31773 amit.gupta 205
        /*
206
         * # No need to validate duplicate items since there are only two ways # to add
207
         * items to a cart and both of them check whether the item being # added is a
208
         * duplicate of an already existing item.
209
         */
28653 amit.gupta 210
 
35947 amit 211
        Cart cart = cartRepository.selectById(cartId);
31773 amit.gupta 212
        List<CartLine> cartLines = cartLineRepository.selectAllByCart(cartId);
28653 amit.gupta 213
 
31792 amit.gupta 214
        //User saholicUser = saholicUserRepository.selectByCartId(cartId);
28653 amit.gupta 215
 
31773 amit.gupta 216
        int totalQty = 0;
217
        double totalAmount = 0;
218
        CartResponse cartResponse = new CartResponse();
219
        List<CartMessage> cartMessages = new ArrayList<>();
220
        List<CartItemResponseModel> cartItemModels = new ArrayList<>();
221
        cartResponse.setCartMessages(cartMessages);
222
        cartResponse.setCartItems(cartItemModels);
28653 amit.gupta 223
 
31773 amit.gupta 224
        int cartMessageChanged = 0;
225
        int cartMessageOOS = 0;
226
        int cartMessageUndeliverable = 0;
28653 amit.gupta 227
 
31773 amit.gupta 228
        Set<Integer> itemIds = cartLines.stream().map(x -> x.getItemId()).collect(Collectors.toSet());
31783 amit.gupta 229
        logger.info("Item ids {}", itemIds);
31773 amit.gupta 230
        List<TagListing> tagListings = tagListingRepository.selectByItemIdsAndTagIds(itemIds, tagIds);
231
        Map<Integer, TagListing> tagListingsMap = tagListings.stream()
232
                .collect(Collectors.toMap(x -> x.getItemId(), x -> x));
28653 amit.gupta 233
 
35493 amit 234
        // N+1 fix: Pre-fetch all items before the loop
235
        Map<Integer, Item> itemMap = itemRepository.selectByIds(itemIds).stream()
236
                .collect(Collectors.toMap(Item::getId, item -> item));
237
 
31773 amit.gupta 238
        User user = saholicUserRepository.selectByCartId(cartId);
239
        FofoStore fs = fofoStoreRepository.selectByRetailerId(user.getId());
240
        Map<Integer, Integer> warehouseItemQtyMap = saholicInventoryService.getSaholicNetAvailability(fs.getWarehouseId(), new ArrayList<>(itemIds));
35170 vikas 241
        PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(fs.getId(), LocalDate.now());
35140 ranu 242
        // Get in-transit data for this warehouse
243
        List<WarehouseIntransitDataModel> warehouseIntransitDataModels =
244
                saholicInventoryService.getWarehouseIntransistDataList().stream()
245
                        .filter(x -> x.getWarehouseId() == fs.getWarehouseId())
246
                        .collect(Collectors.toList());
28653 amit.gupta 247
 
35140 ranu 248
        // Add in-transit quantities into the map
249
        for (WarehouseIntransitDataModel intransitData : warehouseIntransitDataModels) {
250
            if (intransitData.getQty() > 0) {
251
                int itemId = intransitData.getItemId();
252
                int existingQty = warehouseItemQtyMap.getOrDefault(itemId, 0);
253
                warehouseItemQtyMap.put(itemId, existingQty + intransitData.getQty());
254
            }
255
        }
31773 amit.gupta 256
        cart.setTotalPrice(0);
257
        int nonAccessoryQuantity = 0;
37792 amit 258
        int carryBagAllowance = carryBagAllowance(cartLines.stream()
259
                .collect(Collectors.toMap(CartLine::getItemId, CartLine::getQuantity, Integer::sum)), itemMap, tagListingsMap);
260
        CarryBagQuote carryBagQuote = null;
31773 amit.gupta 261
        for (CartLine cartLine : cartLines) {
262
            CartItemResponseModel cartItemResponseModel = new CartItemResponseModel();
263
            int oldEstimate = cartLine.getEstimate();
264
            int itemId = cartLine.getItemId();
35493 amit 265
            // N+1 fix: Use pre-fetched itemMap instead of querying per item
266
            Item item = itemMap.get(itemId);
267
            if (item == null) {
31773 amit.gupta 268
                logger.info("Error finding item with id {}", itemId);
269
                cartLineRepository.delete(cartLine);
270
                continue;
271
            }
35493 amit 272
            cartItemResponseModel.setTitle(item.getItemDescriptionNoColor());
31773 amit.gupta 273
            cartItemResponseModel.setItemId(itemId);
274
            cartItemResponseModel.setQuantity(cartLine.getQuantity());
275
            cartItemResponseModel.setColor(item.getColor());
276
            cartItemResponseModel.setCatalogItemId(item.getCatalogItemId());
277
            cartItemResponseModel.setMinBuyQuantity(1);
278
            cartItemResponseModel.setQuantityStep(1);
32588 amit.gupta 279
            cartItemResponseModel.setMaxQuantity(400);
31773 amit.gupta 280
            int currentAvailability = warehouseItemQtyMap.get(itemId) == null ? 0 : warehouseItemQtyMap.get(itemId);
281
            int oldAvailability = cartLine.getAvailability();
282
            cartItemResponseModel.setAvailability(currentAvailability);
28653 amit.gupta 283
 
31773 amit.gupta 284
            //Current availability is less than required quantity
285
            if (currentAvailability < cartLine.getQuantity()) {
286
                //Current Availability is reduced
287
                if (oldAvailability > currentAvailability) {
288
                    cartMessageChanged += 1;
289
                }
290
            }
28653 amit.gupta 291
 
31773 amit.gupta 292
            //As of now one can buy upto 100 Qty
293
            if (cartLine.getQuantity() > cartItemResponseModel.getMaxQuantity()) {
294
                cartMessageChanged +=1;
295
                cartLine.setQuantity(cartItemResponseModel.getMaxQuantity());
296
            }
28653 amit.gupta 297
 
31773 amit.gupta 298
            if (item.getCategoryId() == 10006 || item.getCategoryId() == 10010) {
299
                nonAccessoryQuantity += cartItemResponseModel.getQuantity();
300
                cartItemResponseModel.setCategoryName("mobile");
301
            }
37792 amit 302
            if (itemId == ProfitMandiConstants.ITEM_CARRY_BAG) {
303
                carryBagQuote = carryBagQuote(partnerType, carryBagAllowance, cartLine.getQuantity(), tagListingsMap.get(itemId));
304
                cartLine.setActualPrice(carryBagQuote.getUnitPrice());
305
                cartItemResponseModel.setSellingPrice(cartLine.getActualPrice());
35170 vikas 306
            } else {
35573 amit 307
                // Check for price mismatch between cart and current TagListing
308
                TagListing currentTagListing = tagListingsMap.get(itemId);
309
                if (currentTagListing != null) {
310
                    float cartPrice = cartLine.getActualPrice();
311
                    float currentPrice = currentTagListing.getSellingPrice();
35574 amit 312
 
313
                    // If cart price is 0 or unset, silently update to current price (client bug)
314
                    if (cartPrice < 0.01f) {
315
                        logger.info("Cart price was 0/unset for itemId {}, setting to current price {}",
316
                            itemId, currentPrice);
317
                        cartLine.setActualPrice(currentPrice);
318
                    }
319
                    // Use tolerance comparison to avoid float precision false positives
320
                    else if (Math.abs(cartPrice - currentPrice) > 0.01f) {
35573 amit 321
                        cartMessageChanged += 1;
322
                        String priceChangeMsg = String.format("Price updated for %s: Rs. %.2f to Rs. %.2f",
323
                            item.getItemDescriptionNoColor(), cartPrice, currentPrice);
324
                        CartMessage cartMessage = new CartMessage();
325
                        cartMessage.setMessageText(priceChangeMsg);
326
                        cartMessage.setType("PRICE_CHANGED");
327
                        cartMessages.add(cartMessage);
328
                        logger.info("Price mismatch detected for itemId {}: cart price {} vs current price {}",
329
                            itemId, cartPrice, currentPrice);
330
                        // Update cart line with current price
331
                        cartLine.setActualPrice(currentPrice);
332
                    }
333
                }
35170 vikas 334
                cartItemResponseModel.setSellingPrice(cartLine.getActualPrice());
335
            }
28653 amit.gupta 336
 
31773 amit.gupta 337
            //if (availability > 0) {
338
            cart.setTotalPrice(cart.getTotalPrice() + (cartLine.getActualPrice() * cartLine.getQuantity()));
339
            cartItemResponseModel.setQuantity(cartLine.getQuantity());
340
            cartItemResponseModel.setEstimate(2);
341
            cartLine.setEstimate(cartItemResponseModel.getEstimate());
342
            cart.setUpdateTimestamp(LocalDateTime.now());
28653 amit.gupta 343
 
28166 tejbeer 344
 
31773 amit.gupta 345
            totalAmount += cartLine.getActualPrice() * cartLine.getQuantity();
346
            totalQty += cartItemResponseModel.getQuantity();
347
            cartResponse.getCartItems().add(cartItemResponseModel);
28166 tejbeer 348
 
31773 amit.gupta 349
        }
350
        if (cart.getCheckoutTimestamp() != null) {
351
            if (cart.getUpdateTimestamp().isBefore(cart.getCheckoutTimestamp())) {
352
                cart.setCheckoutTimestamp(null);
353
            }
354
        }
355
        cartResponse.setTotalQty(totalQty);
356
        cartResponse.setTotalAmount(totalAmount);
357
        cartResponse.setNonAccessoryQuantity(nonAccessoryQuantity);
37792 amit 358
        cartResponse.setCarryBag(carryBagQuote != null ? carryBagQuote
359
                : carryBagQuote(partnerType, carryBagAllowance, 0, tagListingRepository.selectByItemId(ProfitMandiConstants.ITEM_CARRY_BAG)));
31773 amit.gupta 360
        cartResponse.setShippingCharge(0);
361
        cartResponse.setCartMessageChanged(cartMessageChanged);
362
        cartResponse.setCartMessageOOS(cartMessageOOS);
363
        cartResponse.setCartMessageUndeliverable(cartMessageUndeliverable);
364
        cartResponse.setCod(false);
365
        return cartResponse;
366
    }
28653 amit.gupta 367
 
31773 amit.gupta 368
    @Override
37143 amit 369
    public void addItemsToCart(int cartId, int fofoId, List<CartItem> cartItems) throws ProfitMandiBusinessException {
370
        List<CartItem> requestedItems = cartItems.stream().filter(x -> x.getQuantity() > 0)
371
                .collect(Collectors.toList());
372
        if (!requestedItems.isEmpty()) {
373
            List<String> requestedBrands = itemRepository
374
                    .selectByIds(requestedItems.stream().map(CartItem::getItemId).collect(Collectors.toSet()))
375
                    .stream().map(Item::getBrand).distinct().collect(Collectors.toList());
376
            brandsService.validateOrderableBrands(fofoId, requestedBrands);
377
        }
378
        this.addItemsToCart(cartId, cartItems);
379
    }
380
 
381
    @Override
31773 amit.gupta 382
    public void addItemsToCart(int cartId, List<CartItem> cartItems) throws ProfitMandiBusinessException {
37706 amit 383
        // Take the cart row BEFORE any line is touched -- see CartRepository.selectByIdForUpdate.
384
        // Inserting a line shared-locks this same row anyway via line_cart_id_fk, so without this
385
        // the lock order depends on which statement happens to run first and two concurrent edits
386
        // to one cart can deadlock.
387
        cartRepository.selectByIdForUpdate(cartId);
31773 amit.gupta 388
        logger.info("cart items {}", cartItems);
389
        cartItems = cartItems.stream().filter(x -> x.getQuantity() > 0).collect(Collectors.toList());
390
        Map<Integer, Integer> itemQuantityMap = cartItems.stream()
391
                .collect(Collectors.toMap(x -> x.getItemId(), x -> x.getQuantity()));
392
        List<CartLine> cartLines = cartLineRepository.selectAllByCart(cartId);
31781 amit.gupta 393
        Map<Integer, CartLine> itemCartLineMap = cartLines.stream().collect(Collectors.toMap(x->x.getItemId(), x->x));
31773 amit.gupta 394
        // Delete cartLines with 0 values
395
        for (CartLine cartLine : cartLines) {
396
            Integer quantity = itemQuantityMap.get(cartLine.getItemId());
397
            if (quantity == null || quantity.intValue() == 0) {
398
                cartLineRepository.delete(cartLine);
399
            } else {
400
                cartLine.setQuantity(itemQuantityMap.get(cartLine.getItemId()));
401
                cartLine.setUpdateTimestapm(LocalDateTime.now());
402
            }
403
        }
404
        for (CartItem cartItem : cartItems) {
31781 amit.gupta 405
            if (!itemCartLineMap.containsKey(cartItem.getItemId())) {
31773 amit.gupta 406
                CartLine cartLineNew = new CartLine();
407
                cartLineNew.setItemId(cartItem.getItemId());
408
                cartLineNew.setQuantity(cartItem.getQuantity());
409
                cartLineNew.setCartId(cartId);
32493 amit.gupta 410
                cartLineNew.setActualPrice((float) cartItem.getSellingPrice());
31773 amit.gupta 411
                cartLineNew.setCreateTimestamp(LocalDateTime.now());
412
                cartLineRepository.persist(cartLineNew);
413
            }
414
        }
29327 tejbeer 415
 
31773 amit.gupta 416
    }
29327 tejbeer 417
 
31773 amit.gupta 418
    @Override
419
    public void addAddressToCart(int cartId, long addressId) throws ProfitMandiBusinessException {
35947 amit 420
        Cart cart = cartRepository.selectById(cartId);
31773 amit.gupta 421
        cart.setAddressId((int) addressId);
29404 tejbeer 422
 
31773 amit.gupta 423
    }
29404 tejbeer 424
 
31773 amit.gupta 425
    @Override
37792 amit 426
    public CarryBagQuote getCarryBagQuote(int fofoId, Map<Integer, Integer> itemQty) throws ProfitMandiBusinessException {
427
        Set<Integer> itemIds = new HashSet<>(itemQty.keySet());
428
        itemIds.add(ProfitMandiConstants.ITEM_CARRY_BAG);
429
        Map<Integer, Item> itemMap = itemRepository.selectByIds(itemIds).stream()
430
                .collect(Collectors.toMap(Item::getId, x -> x));
431
        Map<Integer, TagListing> tagListingsMap = tagListingRepository.selectByItemIdsAndTagIds(itemIds, tagIds).stream()
432
                .collect(Collectors.toMap(TagListing::getItemId, x -> x, (a, b) -> a));
433
        return carryBagQuote(partnerTypeChangeService.getTypeOnDate(fofoId, LocalDate.now()),
434
                carryBagAllowance(itemQty, itemMap, tagListingsMap),
435
                itemQty.getOrDefault(ProfitMandiConstants.ITEM_CARRY_BAG, 0),
436
                tagListingsMap.get(ProfitMandiConstants.ITEM_CARRY_BAG));
437
    }
29404 tejbeer 438
 
37792 amit 439
    @Override
440
    public List<CartLine> splitCarryBagLine(int fofoId, List<CartLine> cartLines) throws ProfitMandiBusinessException {
441
        CartLine bagLine = cartLines.stream()
442
                .filter(x -> x.getItemId() == ProfitMandiConstants.ITEM_CARRY_BAG).findFirst().orElse(null);
443
        if (bagLine == null) return cartLines;
444
        CarryBagQuote quote = this.getCarryBagQuote(fofoId, cartLines.stream()
445
                .collect(Collectors.toMap(CartLine::getItemId, CartLine::getQuantity, Integer::sum)));
446
        List<CartLine> split = cartLines.stream().filter(x -> x != bagLine).collect(Collectors.toList());
447
        addCarryBagPart(split, bagLine, quote.getFlatQty(), quote.getFlatPrice());
448
        addCarryBagPart(split, bagLine, quote.getListingQty(), quote.getListingPrice());
449
        return split;
31773 amit.gupta 450
    }
29404 tejbeer 451
 
37792 amit 452
    // A detached copy of the bag line - never persisted, the cart keeps its single line
453
    private static void addCarryBagPart(List<CartLine> lines, CartLine bagLine, int qty, float price) {
454
        if (qty <= 0) return;
455
        CartLine part = new CartLine();
456
        BeanUtils.copyProperties(bagLine, part);
457
        part.setQuantity(qty);
458
        part.setActualPrice(price);
459
        lines.add(part);
460
    }
461
 
462
    // Bronze partners pay the listing price for every bag
463
    private static CarryBagQuote carryBagQuote(PartnerType partnerType, int allowance, int bags, TagListing bagListing) {
464
        return new CarryBagQuote(allowance, bags, partnerType != PartnerType.BRONZE, CARRY_BAG_FLAT_PRICE, bagListing.getSellingPrice());
465
    }
466
 
467
    /** One carry bag per unit of a smartphone selling above Rs. 12,000. */
468
    private static int carryBagAllowance(Map<Integer, Integer> itemQty, Map<Integer, Item> itemMap,
469
                                         Map<Integer, TagListing> tagListingsMap) {
470
        int allowance = 0;
471
        for (Entry<Integer, Integer> e : itemQty.entrySet()) {
472
            Item item = itemMap.get(e.getKey());
473
            TagListing tagListing = tagListingsMap.get(e.getKey());
474
            if (item != null && tagListing != null && item.getCategoryId() == ProfitMandiConstants.MOBILE_CATEGORY_ID
475
                    && tagListing.getSellingPrice() > CARRY_BAG_MIN_PHONE_PRICE) {
476
                allowance += e.getValue();
477
            }
478
        }
479
        return allowance;
480
    }
481
 
31773 amit.gupta 482
    @Override
483
    public CartModel removeFromCart(int cartId, int itemId) {
484
        // TODO Auto-generated method stub
485
        return null;
486
    }
29327 tejbeer 487
 
31773 amit.gupta 488
    @Override
489
    public List<FocusedShortageModel> focusedModelShortageValidation(int fofoId,
490
                                                                     Map<Integer, Integer> catalogCartQtyMap) throws ProfitMandiBusinessException {
29327 tejbeer 491
 
35690 amit 492
        Map<Integer, Long> inStockItemModel = currentInventorySnapshotRepository.selectSumInMobileStockGroupByCatalog(fofoId).stream()
31773 amit.gupta 493
                .collect(Collectors.toMap(x -> x.getCatalogItemId(), x -> x.getQty()));
29327 tejbeer 494
 
35690 amit 495
        Map<Integer, Long> itempendingIndent = transactionService.getInTransitOrders(fofoId).stream()
31773 amit.gupta 496
                .collect(Collectors.groupingBy(x -> x.getLineItem().getItem().getCatalogItemId(),
497
                        Collectors.summingLong(x -> (long) x.getLineItem().getQuantity())));
29327 tejbeer 498
 
35690 amit 499
        Map<Integer, Long> grnItemPendingOrders = orderRepository.selectPendingGrnOrders(fofoId).stream()
31773 amit.gupta 500
                .collect(Collectors.groupingBy(x -> x.getLineItem().getItem().getCatalogItemId(),
501
                        Collectors.summingLong(x -> (long) x.getLineItem().getQuantity())));
29327 tejbeer 502
 
31773 amit.gupta 503
        FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
29327 tejbeer 504
 
37143 amit 505
        List<String> retailerBlockBrands = brandsService.restrictedBrands(fofoId);
29327 tejbeer 506
 
35690 amit 507
        List<PartnerRegion> partnerRegions = partnerRegionRepository.selectByfofoId(fofoId);
508
        Map<Integer, Integer> focusedModelMap;
31773 amit.gupta 509
        if (partnerRegions.size() > 0) {
510
            focusedModelMap = focusedModelRepository
511
                    .selectAllByRegionIds(
512
                            partnerRegions.stream().map(x -> x.getRegionId()).collect(Collectors.toList()))
513
                    .stream().collect(Collectors.toMap(x -> x.getCatalogId(), x -> x.getMinimumQty()));
514
        } else {
515
            focusedModelMap = new HashMap<>();
516
        }
29327 tejbeer 517
 
35690 amit 518
        return focusedModelShortageValidation(fofoId, catalogCartQtyMap, inStockItemModel,
519
                itempendingIndent, grnItemPendingOrders, fofoStore, retailerBlockBrands, focusedModelMap);
520
    }
521
 
522
    @Override
523
    public List<FocusedShortageModel> focusedModelShortageValidation(int fofoId,
524
                                                                     Map<Integer, Integer> catalogCartQtyMap,
525
                                                                     Map<Integer, Long> inStockItemModel,
526
                                                                     Map<Integer, Long> itempendingIndent,
527
                                                                     Map<Integer, Long> grnItemPendingOrders,
528
                                                                     FofoStore fofoStore,
529
                                                                     List<String> retailerBlockBrands,
530
                                                                     Map<Integer, Integer> focusedModelMap) throws ProfitMandiBusinessException {
531
 
532
        logger.info("fofoId {}", fofoId);
533
 
534
        focusedModelVariantMap.put(1022771, Arrays.asList(1022771));
535
        focusedModelVariantMap.put(1023025, Arrays.asList(1022975, 1022945));
536
        focusedModelVariantMap.put(1023027, Arrays.asList(1022706));
537
        focusedModelVariantMap.put(1022976, Arrays.asList(1022744));
538
        focusedModelVariantMap.put(1023045, Arrays.asList(1022768));
539
        focusedModelVariantMap.put(1023066, Arrays.asList(1022858));
540
 
31773 amit.gupta 541
        Map<Integer, Integer> catalogItemAailabilityMap = new HashMap<>();
29327 tejbeer 542
 
31773 amit.gupta 543
        for (Entry<Integer, Integer> fm : focusedModelMap.entrySet()) {
544
            List<Item> items = itemRepository.selectAllByCatalogItemId(fm.getKey());
545
            int allColorNetAvailability = 0;
546
            for (Item item : items) {
547
                if (retailerBlockBrands.contains(item.getBrand()))
548
                    continue;
549
                List<SaholicCISTable> currentAvailability = saholicCISTableRepository.selectByItemWarehouse(item.getId(), fofoStore.getWarehouseId());
29327 tejbeer 550
 
31773 amit.gupta 551
                if (currentAvailability != null) {
552
                    allColorNetAvailability += currentAvailability.stream()
553
                            .collect(Collectors.summingInt(SaholicCISTable::getNetAvailability));
554
                }
555
            }
556
            catalogItemAailabilityMap.put(fm.getKey(), allColorNetAvailability);
557
        }
29327 tejbeer 558
 
31773 amit.gupta 559
        List<FocusedShortageModel> focusedModelShortageList = new ArrayList<>();
29327 tejbeer 560
 
31773 amit.gupta 561
        for (Entry<Integer, Integer> fm : focusedModelMap.entrySet()) {
29327 tejbeer 562
 
31773 amit.gupta 563
            logger.info("fm {}", fm);
29404 tejbeer 564
 
31773 amit.gupta 565
            long overallStock = (inStockItemModel.get(fm.getKey()) == null ? 0 : inStockItemModel.get(fm.getKey()))
566
                    + (itempendingIndent.get(fm.getKey()) == null ? 0 : itempendingIndent.get(fm.getKey()))
567
                    + (grnItemPendingOrders.get(fm.getKey()) == null ? 0 : grnItemPendingOrders.get(fm.getKey()));
568
            logger.info("overallStock {}", overallStock);
29404 tejbeer 569
 
31773 amit.gupta 570
            // Blocked brands available quantity is discussed to zero
571
            long warehouseStock = catalogItemAailabilityMap.get(fm.getKey()) == null ? 0
572
                    : catalogItemAailabilityMap.get(fm.getKey());
573
            logger.info("warehouseStock {}", warehouseStock);
29404 tejbeer 574
 
31773 amit.gupta 575
            long cartValue = catalogCartQtyMap.get(fm.getKey()) == null ? 0 : catalogCartQtyMap.get(fm.getKey());
29404 tejbeer 576
 
31773 amit.gupta 577
            logger.info("cartValue" + cartValue);
578
            long totalStock = overallStock + cartValue;
579
            logger.info("totalStock" + totalStock);
29404 tejbeer 580
 
31773 amit.gupta 581
            long shortQty = Math.min(fm.getValue() - totalStock, warehouseStock);
582
            logger.info("shortQty {}", shortQty);
29404 tejbeer 583
 
31773 amit.gupta 584
            if (shortQty > 0) {
585
                if (focusedModelVariantMap.get(fm.getKey()) != null) {
586
                    List<Integer> variantCatalogIds = focusedModelVariantMap.get(fm.getKey());
587
                    logger.info("variantCatalogIds {}", variantCatalogIds);
29404 tejbeer 588
 
31773 amit.gupta 589
                    int variantAvailability = 0;
590
                    for (Integer vc : variantCatalogIds) {
591
                        long variantOverallStock = (inStockItemModel.get(vc) == null ? 0 : inStockItemModel.get(vc))
592
                                + (itempendingIndent.get(vc) == null ? 0 : itempendingIndent.get(vc))
593
                                + (grnItemPendingOrders.get(vc) == null ? 0 : grnItemPendingOrders.get(vc));
594
                        logger.info("variantOverallStock {}", variantOverallStock);
29404 tejbeer 595
 
31773 amit.gupta 596
                        // Blocked brands available quantity is discussed to zero
597
                        long variantWarehouseStock = catalogItemAailabilityMap.get(vc) == null ? 0
598
                                : catalogItemAailabilityMap.get(vc);
599
                        logger.info("variantWarehouseStock {}", variantWarehouseStock);
29404 tejbeer 600
 
31773 amit.gupta 601
                        long variantCartValue = catalogCartQtyMap.get(vc) == null ? 0 : catalogCartQtyMap.get(vc);
29404 tejbeer 602
 
31773 amit.gupta 603
                        logger.info("variantCartValue" + variantCartValue);
604
                        long variantTotalStock = variantOverallStock + variantCartValue;
605
                        logger.info("variantTotalStock" + variantTotalStock);
29404 tejbeer 606
 
31773 amit.gupta 607
                        variantAvailability += (int) variantTotalStock;
29327 tejbeer 608
 
31773 amit.gupta 609
                    }
29327 tejbeer 610
 
31773 amit.gupta 611
                    logger.info("variantAvailability {}", variantAvailability);
29327 tejbeer 612
 
31773 amit.gupta 613
                    shortQty = shortQty - variantAvailability;
29327 tejbeer 614
 
31773 amit.gupta 615
                }
616
            }
29327 tejbeer 617
 
31773 amit.gupta 618
            logger.info("shortQty" + shortQty);
29327 tejbeer 619
 
31773 amit.gupta 620
            if (shortQty > 0) {
29327 tejbeer 621
 
31773 amit.gupta 622
                Map<Integer, Integer> requiredItemQty = new HashMap<>();
29327 tejbeer 623
 
31773 amit.gupta 624
                List<Item> it = itemRepository.selectAllByCatalogItemId(fm.getKey());
625
                FocusedShortageModel fms = new FocusedShortageModel();
626
                fms.setShortageQty((int) shortQty);
627
                fms.setCatalogId(fm.getKey());
628
                fms.setAvailabitiy(fm.getValue());
629
                fms.setInStock(overallStock);
29327 tejbeer 630
 
31773 amit.gupta 631
                fms.setItemName(it.get(0).getBrand() + it.get(0).getModelNumber() + it.get(0).getModelName());
29327 tejbeer 632
 
31773 amit.gupta 633
                Map<Integer, Integer> itemQtyMap = new HashMap<>();
29327 tejbeer 634
 
31773 amit.gupta 635
                for (Item i : it) {
29327 tejbeer 636
 
31773 amit.gupta 637
                    List<SaholicCISTable> ca = saholicCISTableRepository.selectByItemWarehouse(i.getId(), fofoStore.getWarehouseId());
638
                    if (ca != null) {
639
                        itemQtyMap.put(i.getId(),
640
                                ca.stream().collect(Collectors.summingInt(SaholicCISTable::getNetAvailability)));
641
                    }
642
                }
29327 tejbeer 643
 
31773 amit.gupta 644
                itemQtyMap = itemQtyMap.entrySet().stream()
645
                        .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).collect(Collectors
646
                                .toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));
29327 tejbeer 647
 
31773 amit.gupta 648
                for (long i = shortQty; i > 0; i--) {
649
                    if (shortQty == 0) {
650
                        break;
651
                    }
29327 tejbeer 652
 
31773 amit.gupta 653
                    for (Entry<Integer, Integer> itemQty : itemQtyMap.entrySet()) {
29327 tejbeer 654
 
31773 amit.gupta 655
                        int availbleQty = itemQty.getValue();
656
                        if (availbleQty == 0) {
657
                            break;
658
                        }
659
                        if (requiredItemQty.get(itemQty.getKey()) == null) {
660
                            requiredItemQty.put(itemQty.getKey(), 1);
661
                            availbleQty = availbleQty - 1;
662
                            if (availbleQty != 0) {
663
                                itemQtyMap.put(itemQty.getKey(), availbleQty);
664
                            }
665
                            shortQty -= 1;
666
                        } else {
29327 tejbeer 667
 
31773 amit.gupta 668
                            int qty = requiredItemQty.get(itemQty.getKey());
29327 tejbeer 669
 
31773 amit.gupta 670
                            requiredItemQty.put(itemQty.getKey(), qty + 1);
29327 tejbeer 671
 
31773 amit.gupta 672
                            availbleQty = availbleQty - 1;
673
                            if (availbleQty != 0) {
674
                                itemQtyMap.put(itemQty.getKey(), availbleQty);
675
                            }
676
                            shortQty -= 1;
677
                        }
29327 tejbeer 678
 
31773 amit.gupta 679
                        if (shortQty == 0) {
680
                            break;
681
                        }
29327 tejbeer 682
 
31773 amit.gupta 683
                    }
29327 tejbeer 684
 
31773 amit.gupta 685
                }
29327 tejbeer 686
 
31773 amit.gupta 687
                Set<CartItem> cartItems = new HashSet<>();
688
                for (Entry<Integer, Integer> itemQtySet : requiredItemQty.entrySet()) {
29327 tejbeer 689
 
31773 amit.gupta 690
                    CartItem ci = new CartItem();
691
                    Item item = itemRepository.selectById(itemQtySet.getKey());
692
                    TagListing tl = tagListingRepository.selectByItemId(item.getId());
693
                    ci.setItemId(item.getId());
694
                    ci.setQuantity(itemQtySet.getValue());
695
                    ci.setSellingPrice(tl.getSellingPrice());
696
                    cartItems.add(ci);
697
 
698
                }
699
                fms.setCartItems(cartItems);
700
 
701
                // fms.setItemQtyAvailability(requiredItemQty);
702
 
703
                focusedModelShortageList.add(fms);
704
 
705
            }
706
 
707
        }
708
 
709
        logger.info("focusedModelShortageList {}", focusedModelShortageList);
710
        return focusedModelShortageList;
711
    }
712
 
33172 tejus.loha 713
    @Override
714
    public UserCart setCartItems(int fofoId, List<CartItem> cartItems) throws ProfitMandiBusinessException {
715
        User user = saholicUserRepository.selectById(fofoId);
716
        this.clearCart(user.getActiveCartId());
37143 amit 717
        this.addItemsToCart(user.getActiveCartId(), fofoId, cartItems);
33172 tejus.loha 718
 
719
        UserCart userCart = new UserCart();
720
        userCart.setCartId(user.getActiveCartId());
721
        userCart.setUserId(user.getId());
722
        return userCart;
723
    }
724
 
26522 amit.gupta 725
}