Subversion Repositories SmartDukaan

Rev

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

Rev 37015 Rev 37084
Line 4... Line 4...
4
import com.spice.profitmandi.common.model.ProfitMandiConstants;
4
import com.spice.profitmandi.common.model.ProfitMandiConstants;
5
import com.spice.profitmandi.common.model.UserInfo;
5
import com.spice.profitmandi.common.model.UserInfo;
6
import com.spice.profitmandi.dao.cart.CartService;
6
import com.spice.profitmandi.dao.cart.CartService;
7
import com.spice.profitmandi.dao.cart.v2.CartValidationService;
7
import com.spice.profitmandi.dao.cart.v2.CartValidationService;
8
import com.spice.profitmandi.dao.cart.v2.CheckoutValidationResult;
8
import com.spice.profitmandi.dao.cart.v2.CheckoutValidationResult;
-
 
9
import com.spice.profitmandi.dao.cart.v2.HydratedCart;
-
 
10
import com.spice.profitmandi.dao.cart.v2.HydratedLine;
-
 
11
import com.spice.profitmandi.dao.cart.v2.LineStatus;
9
import com.spice.profitmandi.dao.cart.v2.OpenCartValidationResult;
12
import com.spice.profitmandi.dao.cart.v2.OpenCartValidationResult;
-
 
13
import com.spice.profitmandi.dao.cart.v2.PricingBreakup;
10
import com.spice.profitmandi.dao.cart.v2.SaleType;
14
import com.spice.profitmandi.dao.cart.v2.SaleType;
11
import com.spice.profitmandi.dao.entity.catalog.Item;
15
import com.spice.profitmandi.dao.entity.catalog.Item;
12
import com.spice.profitmandi.dao.entity.catalog.TagListing;
16
import com.spice.profitmandi.dao.entity.catalog.TagListing;
13
import com.spice.profitmandi.dao.entity.fofo.PartnerType;
17
import com.spice.profitmandi.dao.entity.fofo.PartnerType;
14
import com.spice.profitmandi.dao.entity.user.CartLine;
18
import com.spice.profitmandi.dao.entity.user.CartLine;
Line 29... Line 33...
29
import org.springframework.http.ResponseEntity;
33
import org.springframework.http.ResponseEntity;
30
import org.springframework.ui.Model;
34
import org.springframework.ui.Model;
31
import org.springframework.web.bind.annotation.*;
35
import org.springframework.web.bind.annotation.*;
32
 
36
 
33
import javax.servlet.http.HttpServletRequest;
37
import javax.servlet.http.HttpServletRequest;
-
 
38
import java.math.BigDecimal;
-
 
39
import java.math.RoundingMode;
34
import java.time.LocalDate;
40
import java.time.LocalDate;
35
import java.util.ArrayList;
41
import java.util.ArrayList;
36
import java.util.Arrays;
42
import java.util.Arrays;
37
import java.util.HashSet;
43
import java.util.HashSet;
38
import java.util.List;
44
import java.util.List;
Line 143... Line 149...
143
    public ResponseEntity<?> openCart(HttpServletRequest request)
149
    public ResponseEntity<?> openCart(HttpServletRequest request)
144
            throws ProfitMandiBusinessException {
150
            throws ProfitMandiBusinessException {
145
        java.util.Optional<AuthCtx> auth = resolveAuth(request);
151
        java.util.Optional<AuthCtx> auth = resolveAuth(request);
146
        if (!auth.isPresent()) return unauthorized();
152
        if (!auth.isPresent()) return unauthorized();
147
        AuthCtx ctx = auth.get();
153
        AuthCtx ctx = auth.get();
148
        OpenCartValidationResult result = cartValidationService.validateForOpen(
154
        OpenCartValidationResult result = validateAndApplyCarryBagPrice(
149
                ctx.cartId, ctx.storeId);
155
                ctx.cartId, ctx.storeId);
150
        return ResponseEntity.ok(ApiResponse.success(result));
156
        return ResponseEntity.ok(ApiResponse.success(result));
151
    }
157
    }
152
 
158
 
153
    /** STEP 2 — hard validation immediately before payment. Returns
159
    /** STEP 2 — hard validation immediately before payment. Returns
Line 232... Line 238...
232
        // Skip carry bag rebalance if user explicitly changed carry bag qty
238
        // Skip carry bag rebalance if user explicitly changed carry bag qty
233
        if (productId == ProfitMandiConstants.ITEM_CARRY_BAG) {
239
        if (productId == ProfitMandiConstants.ITEM_CARRY_BAG) {
234
            enrichPrices(ctx, desired);
240
            enrichPrices(ctx, desired);
235
            cartService.addItemsToCart(ctx.cartId, desired);
241
            cartService.addItemsToCart(ctx.cartId, desired);
236
            return ResponseEntity.ok(ApiResponse.success(
242
            return ResponseEntity.ok(ApiResponse.success(
237
                    cartValidationService.validateForOpen(ctx.cartId, ctx.storeId)));
243
                    validateAndApplyCarryBagPrice(ctx.cartId, ctx.storeId)));
238
        }
244
        }
239
        return applyAndHydrate(ctx, desired);
245
        return applyAndHydrate(ctx, desired);
240
    }
246
    }
241
 
247
 
242
    /** Remove a single line by productId. */
248
    /** Remove a single line by productId. */
Line 253... Line 259...
253
        // Skip carry bag rebalance if user explicitly removed the carry bag
259
        // Skip carry bag rebalance if user explicitly removed the carry bag
254
        if (productId == ProfitMandiConstants.ITEM_CARRY_BAG) {
260
        if (productId == ProfitMandiConstants.ITEM_CARRY_BAG) {
255
            enrichPrices(ctx, desired);
261
            enrichPrices(ctx, desired);
256
            cartService.addItemsToCart(ctx.cartId, desired);
262
            cartService.addItemsToCart(ctx.cartId, desired);
257
            return ResponseEntity.ok(ApiResponse.success(
263
            return ResponseEntity.ok(ApiResponse.success(
258
                    cartValidationService.validateForOpen(ctx.cartId, ctx.storeId)));
264
                    validateAndApplyCarryBagPrice(ctx.cartId, ctx.storeId)));
259
        }
265
        }
260
        return applyAndHydrate(ctx, desired);
266
        return applyAndHydrate(ctx, desired);
261
    }
267
    }
262
 
268
 
263
    /** Clear the entire cart. */
269
    /** Clear the entire cart. */
Line 267... Line 273...
267
        java.util.Optional<AuthCtx> auth = resolveAuth(request);
273
        java.util.Optional<AuthCtx> auth = resolveAuth(request);
268
        if (!auth.isPresent()) return unauthorized();
274
        if (!auth.isPresent()) return unauthorized();
269
        AuthCtx ctx = auth.get();
275
        AuthCtx ctx = auth.get();
270
        cartService.clearCart(ctx.cartId);
276
        cartService.clearCart(ctx.cartId);
271
        return ResponseEntity.ok(ApiResponse.success(
277
        return ResponseEntity.ok(ApiResponse.success(
272
                cartValidationService.validateForOpen(ctx.cartId, ctx.storeId)));
278
                validateAndApplyCarryBagPrice(ctx.cartId, ctx.storeId)));
273
    }
279
    }
274
 
280
 
275
    /**
281
    /**
276
     * Enriches each desired CartItem with the live selling price, runs the
282
     * Enriches each desired CartItem with the live selling price, runs the
277
     * procurement carry-bag rebalance, applies the change, then returns a
283
     * procurement carry-bag rebalance, applies the change, then returns a
Line 282... Line 288...
282
            throws ProfitMandiBusinessException {
288
            throws ProfitMandiBusinessException {
283
        enrichPrices(ctx, desired);
289
        enrichPrices(ctx, desired);
284
        rebalanceCarryBag(desired, ctx.storeId);
290
        rebalanceCarryBag(desired, ctx.storeId);
285
        cartService.addItemsToCart(ctx.cartId, desired);
291
        cartService.addItemsToCart(ctx.cartId, desired);
286
        return ResponseEntity.ok(ApiResponse.success(
292
        return ResponseEntity.ok(ApiResponse.success(
287
                cartValidationService.validateForOpen(ctx.cartId, ctx.storeId)));
293
                validateAndApplyCarryBagPrice(ctx.cartId, ctx.storeId)));
288
    }
294
    }
289
 
295
 
290
    /**
296
    /**
291
     * Populates {@link CartItem#setSellingPrice(double)} for each non-carry-bag item
297
     * Populates {@link CartItem#setSellingPrice(double)} for each non-carry-bag item
292
     * with the live (MOP - scheme cashback) figure. Preserves the existing value on
298
     * with the live (MOP - scheme cashback) figure. Preserves the existing value on
Line 343... Line 349...
343
            bag.setSellingPrice(resolveCarryBagPrice(fofoId));
349
            bag.setSellingPrice(resolveCarryBagPrice(fofoId));
344
            desired.add(bag);
350
            desired.add(bag);
345
        }
351
        }
346
    }
352
    }
347
 
353
 
-
 
354
    /**
-
 
355
     * Wraps {@link CartValidationService#validateForOpen} and overrides the
-
 
356
     * carry-bag line's LivePrice + rolls up totals using the tier logic that
-
 
357
     * v1's {@code CartServiceImpl.getCartValidation} already applies (lines
-
 
358
     * 271-278). Needed because the shared v2 hydrator prices every line from
-
 
359
     * {@code TagListing.getMop()} without a tier check, so premium partners
-
 
360
     * would otherwise see MRP (₹15) instead of ₹1.
-
 
361
     */
-
 
362
    private OpenCartValidationResult validateAndApplyCarryBagPrice(int cartId, int fofoId)
-
 
363
            throws ProfitMandiBusinessException {
-
 
364
        OpenCartValidationResult result = cartValidationService.validateForOpen(cartId, fofoId);
-
 
365
        if (result == null || result.getCart() == null || result.getCart().getLines() == null) {
-
 
366
            return result;
-
 
367
        }
-
 
368
        HydratedCart cart = result.getCart();
-
 
369
        BigDecimal tierPrice = BigDecimal.valueOf(resolveCarryBagPrice(fofoId))
-
 
370
                .setScale(2, RoundingMode.HALF_UP);
-
 
371
        boolean overridden = false;
-
 
372
        for (HydratedLine line : cart.getLines()) {
-
 
373
            if (line.getProductId() != ProfitMandiConstants.ITEM_CARRY_BAG) continue;
-
 
374
            if (line.getPrice() == null) continue;
-
 
375
            if (line.getPrice().getSelling() == null
-
 
376
                    || line.getPrice().getSelling().compareTo(tierPrice) != 0) {
-
 
377
                line.getPrice().setMrp(tierPrice);
-
 
378
                line.getPrice().setSelling(tierPrice);
-
 
379
                line.getPrice().setSchemeCashback(BigDecimal.ZERO);
-
 
380
                overridden = true;
-
 
381
            }
-
 
382
        }
-
 
383
        if (overridden && cart.getPricing() != null) {
-
 
384
            // Mirrors CartHydrationServiceImpl.computePricing so grand total
-
 
385
            // reflects the overridden carry-bag price.
-
 
386
            BigDecimal subtotal = BigDecimal.ZERO;
-
 
387
            BigDecimal discounts = BigDecimal.ZERO;
-
 
388
            BigDecimal insuranceTotal = BigDecimal.ZERO;
-
 
389
            for (HydratedLine line : cart.getLines()) {
-
 
390
                if (line.getStatus() != LineStatus.ACTIVE || line.getPrice() == null) continue;
-
 
391
                BigDecimal qty = BigDecimal.valueOf(line.getQuantity());
-
 
392
                subtotal = subtotal.add(line.getPrice().getMrp().multiply(qty));
-
 
393
                BigDecimal cashback = line.getPrice().getSchemeCashback() == null
-
 
394
                        ? BigDecimal.ZERO : line.getPrice().getSchemeCashback();
-
 
395
                discounts = discounts.add(cashback.multiply(qty));
-
 
396
                if (line.getInsurance() != null && line.getInsurance().getPremium() != null) {
-
 
397
                    insuranceTotal = insuranceTotal.add(line.getInsurance().getPremium());
-
 
398
                }
-
 
399
            }
-
 
400
            PricingBreakup p = cart.getPricing();
-
 
401
            p.setSubtotal(subtotal);
-
 
402
            p.setLineDiscounts(discounts);
-
 
403
            p.setTaxableBase(subtotal.subtract(discounts));
-
 
404
            p.setGrandTotal(p.getTaxableBase().add(insuranceTotal));
-
 
405
        }
-
 
406
        return result;
-
 
407
    }
-
 
408
 
348
    private float resolveCarryBagPrice(int fofoId) {
409
    private float resolveCarryBagPrice(int fofoId) {
349
        PartnerType tier = null;
410
        PartnerType tier = null;
350
        try {
411
        try {
351
            tier = partnerTypeChangeService.getTypeOnDate(fofoId, LocalDate.now());
412
            tier = partnerTypeChangeService.getTypeOnDate(fofoId, LocalDate.now());
352
        } catch (Exception e) {
413
        } catch (Exception e) {