Subversion Repositories SmartDukaan

Rev

Rev 34341 | Rev 34351 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
23365 ashik.ali 1
package com.spice.profitmandi.service.order;
22859 ashik.ali 2
 
24264 amit.gupta 3
import com.spice.profitmandi.common.enumuration.ItemType;
23202 ashik.ali 4
import com.spice.profitmandi.common.enumuration.SearchType;
33838 ranu 5
import com.spice.profitmandi.common.enumuration.UpgradeOfferPaymentStatus;
22859 ashik.ali 6
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
32420 amit.gupta 7
import com.spice.profitmandi.common.model.*;
23650 amit.gupta 8
import com.spice.profitmandi.common.util.FormattingUtils;
22859 ashik.ali 9
import com.spice.profitmandi.common.util.StringUtils;
23172 ashik.ali 10
import com.spice.profitmandi.common.util.Utils;
29515 tejbeer 11
import com.spice.profitmandi.common.web.client.RestClient;
33873 ranu 12
import com.spice.profitmandi.dao.cart.SmartCartService;
33795 ranu 13
import com.spice.profitmandi.dao.entity.catalog.CustomerOfferItem;
22859 ashik.ali 14
import com.spice.profitmandi.dao.entity.catalog.Item;
25103 amit.gupta 15
import com.spice.profitmandi.dao.entity.catalog.TagListing;
33795 ranu 16
import com.spice.profitmandi.dao.entity.catalog.UpgradeOffer;
32420 amit.gupta 17
import com.spice.profitmandi.dao.entity.dtr.*;
18
import com.spice.profitmandi.dao.entity.fofo.*;
28978 amit.gupta 19
import com.spice.profitmandi.dao.entity.inventory.State;
24917 tejbeer 20
import com.spice.profitmandi.dao.entity.transaction.Order;
22859 ashik.ali 21
import com.spice.profitmandi.dao.entity.user.Address;
22
import com.spice.profitmandi.dao.entity.user.Counter;
23
import com.spice.profitmandi.dao.entity.user.PrivateDealUser;
27516 amit.gupta 24
import com.spice.profitmandi.dao.entity.warehouse.WarehouseInventoryItem;
24264 amit.gupta 25
import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;
23546 ashik.ali 26
import com.spice.profitmandi.dao.enumuration.dtr.PaymentOptionReferenceType;
23650 amit.gupta 27
import com.spice.profitmandi.dao.enumuration.fofo.ReturnType;
22859 ashik.ali 28
import com.spice.profitmandi.dao.enumuration.fofo.ScanType;
23655 amit.gupta 29
import com.spice.profitmandi.dao.enumuration.fofo.SettlementType;
29515 tejbeer 30
import com.spice.profitmandi.dao.enumuration.inventory.ScratchedGift;
28339 tejbeer 31
import com.spice.profitmandi.dao.enumuration.transaction.OrderStatus;
33795 ranu 32
import com.spice.profitmandi.dao.repository.catalog.*;
32420 amit.gupta 33
import com.spice.profitmandi.dao.repository.dtr.*;
34
import com.spice.profitmandi.dao.repository.fofo.*;
24854 amit.gupta 35
import com.spice.profitmandi.dao.repository.inventory.StateRepository;
24917 tejbeer 36
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
22859 ashik.ali 37
import com.spice.profitmandi.dao.repository.user.AddressRepository;
38
import com.spice.profitmandi.dao.repository.user.CounterRepository;
39
import com.spice.profitmandi.dao.repository.user.PrivateDealUserRepository;
27516 amit.gupta 40
import com.spice.profitmandi.dao.repository.warehouse.WarehouseInventoryItemRepository;
25724 amit.gupta 41
import com.spice.profitmandi.service.integrations.zest.InsuranceService;
31274 amit.gupta 42
import com.spice.profitmandi.service.integrations.zest.MobileInsurancePlan;
23418 ashik.ali 43
import com.spice.profitmandi.service.inventory.InventoryService;
23655 amit.gupta 44
import com.spice.profitmandi.service.inventory.PurchaseReturnService;
26891 amit.gupta 45
import com.spice.profitmandi.service.inventory.SaholicInventoryService;
28166 tejbeer 46
import com.spice.profitmandi.service.offers.ItemCriteria;
22859 ashik.ali 47
import com.spice.profitmandi.service.pricing.PricingService;
48
import com.spice.profitmandi.service.scheme.SchemeService;
23655 amit.gupta 49
import com.spice.profitmandi.service.user.RetailerService;
32420 amit.gupta 50
import org.apache.logging.log4j.LogManager;
51
import org.apache.logging.log4j.Logger;
52
import org.hibernate.Session;
53
import org.hibernate.SessionFactory;
54
import org.json.JSONObject;
55
import org.springframework.beans.factory.annotation.Autowired;
56
import org.springframework.beans.factory.annotation.Qualifier;
57
import org.springframework.beans.factory.annotation.Value;
58
import org.springframework.cache.annotation.Cacheable;
59
import org.springframework.core.io.InputStreamResource;
60
import org.springframework.http.HttpHeaders;
61
import org.springframework.http.HttpStatus;
62
import org.springframework.http.ResponseEntity;
63
import org.springframework.stereotype.Component;
22859 ashik.ali 64
 
32420 amit.gupta 65
import javax.persistence.criteria.CriteriaBuilder;
66
import javax.persistence.criteria.CriteriaQuery;
67
import javax.persistence.criteria.Predicate;
68
import javax.persistence.criteria.Root;
69
import java.io.ByteArrayInputStream;
70
import java.io.InputStream;
71
import java.time.LocalDate;
72
import java.time.LocalDateTime;
73
import java.time.LocalTime;
74
import java.util.AbstractMap.SimpleEntry;
75
import java.util.*;
76
import java.util.function.Function;
77
import java.util.stream.Collectors;
78
 
22859 ashik.ali 79
@Component
80
public class OrderServiceImpl implements OrderService {
81
 
32145 tejbeer 82
    private static final Logger LOGGER = LogManager.getLogger(OrderServiceImpl.class);
22859 ashik.ali 83
 
32145 tejbeer 84
    private static Map<String, Integer> serialNumberOrderIdMap = new HashMap<>();
31030 amit.gupta 85
 
32145 tejbeer 86
    static {
87
        serialNumberOrderIdMap.put("862897055749275", 67228);
88
    }
31030 amit.gupta 89
 
32145 tejbeer 90
    @Autowired
91
    @Qualifier("fofoInventoryItemRepository")
92
    private InventoryItemRepository inventoryItemRepository;
27083 amit.gupta 93
 
32145 tejbeer 94
    @Autowired
95
    private StateGstRateRepository stateGstRateRepository;
23650 amit.gupta 96
 
32145 tejbeer 97
    @Autowired
98
    private SaholicInventoryService saholicInventoryService;
27083 amit.gupta 99
 
32145 tejbeer 100
    @Autowired
101
    private LiveDemoBillingRespository liveDemoBillingRespository;
24823 amit.gupta 102
 
32145 tejbeer 103
    @Autowired
104
    private InsuranceService insuranceService;
25724 amit.gupta 105
 
32145 tejbeer 106
    @Autowired
107
    @Qualifier("fofoCurrentInventorySnapshotRepository")
108
    private CurrentInventorySnapshotRepository currentInventorySnapshotRepository;
22859 ashik.ali 109
 
32145 tejbeer 110
    @Autowired
111
    private InvoiceNumberGenerationSequenceRepository invoiceNumberGenerationSequenceRepository;
22859 ashik.ali 112
 
32145 tejbeer 113
    @Autowired
114
    private PurchaseReturnService purchaseReturnService;
23655 amit.gupta 115
 
32145 tejbeer 116
    @Autowired
117
    private RetailerService retailerService;
23655 amit.gupta 118
 
32145 tejbeer 119
    @Autowired
120
    private CustomerRepository customerRepository;
23650 amit.gupta 121
 
32145 tejbeer 122
    @Autowired
123
    private PurchaseReturnItemRepository purchaseReturnItemRepository;
22859 ashik.ali 124
 
32145 tejbeer 125
    @Autowired
126
    private AddressRepository addressRepository;
22859 ashik.ali 127
 
32145 tejbeer 128
    @Autowired
129
    private FofoLineItemRepository fofoLineItemRepository;
22859 ashik.ali 130
 
32145 tejbeer 131
    @Autowired
32816 ranu 132
    private FofoNonSerializeSerialRepository fofoNonSerializeSerialRepository;
133
 
134
    @Autowired
32145 tejbeer 135
    private WarehouseInventoryItemRepository warehouseInventoryItemRepository;
27516 amit.gupta 136
 
32145 tejbeer 137
    @Autowired
138
    private FofoOrderItemRepository fofoOrderItemRepository;
23650 amit.gupta 139
 
32145 tejbeer 140
    @Autowired
141
    private PaymentOptionRepository paymentOptionRepository;
22859 ashik.ali 142
 
32145 tejbeer 143
    @Autowired
144
    private CustomerReturnItemRepository customerReturnItemRepository;
23650 amit.gupta 145
 
32145 tejbeer 146
    @Autowired
147
    @Qualifier("fofoScanRecordRepository")
148
    private ScanRecordRepository scanRecordRepository;
22859 ashik.ali 149
 
32145 tejbeer 150
    @Autowired
151
    private FofoOrderRepository fofoOrderRepository;
22859 ashik.ali 152
 
32145 tejbeer 153
    @Autowired
154
    private RetailerRepository retailerRepository;
22859 ashik.ali 155
 
32145 tejbeer 156
    @Autowired
157
    private UserRepository userRepository;
22859 ashik.ali 158
 
32145 tejbeer 159
    @Autowired
160
    private UserAccountRepository userAccountRepository;
22859 ashik.ali 161
 
32145 tejbeer 162
    @Autowired
163
    private RetailerRegisteredAddressRepository retailerRegisteredAddressRepository;
22859 ashik.ali 164
 
32145 tejbeer 165
    @Autowired
166
    private CustomerAddressRepository customerAddressRepository;
22859 ashik.ali 167
 
32145 tejbeer 168
    @Autowired
169
    @Qualifier("catalogItemRepository")
170
    private ItemRepository itemRepository;
23650 amit.gupta 171
 
32145 tejbeer 172
    @Autowired
173
    private InsuranceProviderRepository insuranceProviderRepository;
23650 amit.gupta 174
 
32145 tejbeer 175
    @Autowired
176
    private InsurancePolicyRepository insurancePolicyRepository;
24917 tejbeer 177
 
32145 tejbeer 178
    @Autowired
179
    private StateRepository stateRepository;
23650 amit.gupta 180
 
32145 tejbeer 181
    @Autowired
182
    private PolicyNumberGenerationSequenceRepository policyNumberGenerationSequenceRepository;
23650 amit.gupta 183
 
32145 tejbeer 184
    @Autowired
185
    private PricingService pricingService;
23650 amit.gupta 186
 
32145 tejbeer 187
    @Autowired
188
    private PrivateDealUserRepository privateDealUserRepository;
23650 amit.gupta 189
 
32145 tejbeer 190
    @Autowired
191
    private TagListingRepository tagListingRepository;
24823 amit.gupta 192
 
32145 tejbeer 193
    @Autowired
194
    private CounterRepository counterRepository;
23650 amit.gupta 195
 
32145 tejbeer 196
    @Autowired
197
    private FofoStoreRepository fofoStoreRepository;
23650 amit.gupta 198
 
32145 tejbeer 199
    @Autowired
200
    private PaymentOptionTransactionRepository paymentOptionTransactionRepository;
23650 amit.gupta 201
 
32145 tejbeer 202
    @Autowired
203
    private SchemeService schemeService;
23650 amit.gupta 204
 
32145 tejbeer 205
    private static final List<Integer> orderIdsConsumed = new ArrayList<>();
28166 tejbeer 206
 
32145 tejbeer 207
    @Autowired
208
    @Qualifier("fofoInventoryService")
209
    private InventoryService inventoryService;
23650 amit.gupta 210
 
32145 tejbeer 211
    @Autowired
212
    private CustomerCreditNoteRepository customerCreditNoteRepository;
23650 amit.gupta 213
 
32145 tejbeer 214
    @Autowired
215
    private OrderRepository orderRepository;
24917 tejbeer 216
 
32145 tejbeer 217
    @Autowired
218
    private HygieneDataRepository hygieneDataRepository;
25640 tejbeer 219
 
32145 tejbeer 220
    @Autowired
221
    private SessionFactory sessionFactory;
28166 tejbeer 222
 
32145 tejbeer 223
    @Autowired
224
    private Mongo mongoClient;
28964 tejbeer 225
 
32145 tejbeer 226
    @Autowired
227
    private PendingOrderRepository pendingOrderRepository;
28964 tejbeer 228
 
32145 tejbeer 229
    @Autowired
33399 ranu 230
 
231
    private PendingOrderService pendingOrderService;
232
 
233
    @Autowired
32145 tejbeer 234
    private PendingOrderItemRepository pendingOrderItemRepository;
28166 tejbeer 235
 
32145 tejbeer 236
    @Autowired
237
    private ScratchOfferRepository scratchOfferRepository;
29515 tejbeer 238
 
32145 tejbeer 239
    @Autowired
240
    RestClient restClient;
29515 tejbeer 241
 
33715 ranu 242
    @Autowired
243
    UpSaleOrderRepository upSaleOrderRepository;
244
 
33795 ranu 245
    @Autowired
246
    private CustomerOfferRepository customerOfferRepository;
247
 
248
    @Autowired
249
    private CustomerOfferItemRepository customerOfferItemRepository;
250
 
251
    @Autowired
252
    private UpgradeOfferRepository upgradeOfferRepository;
253
 
33873 ranu 254
    @Autowired
255
    private SmartCartService smartCartService;
256
 
33895 ranu 257
    @Autowired
258
    private PartnerTypeChangeService partnerTypeChangeService;
259
 
32145 tejbeer 260
    @Value("${prod}")
261
    private boolean prodEnv;
29515 tejbeer 262
 
32145 tejbeer 263
    private static final String SMS_GATEWAY = "http://api.pinnacle.in/index.php/sms/send";
264
    private static final String SENDER = "SMTDKN";
29515 tejbeer 265
 
32145 tejbeer 266
    public static final String APP_DOWNLOAD_BILLING_TEMPLATE_ID = "1507163542403945677";
29515 tejbeer 267
 
32145 tejbeer 268
    public static final String APP_DOWNLOAD_BILLING_OFFER = "Dear Customer, Thank you for purchasing from SmartDukaan pls click %s to download our app to see you invoice and special offers. SmartDukaan";
29515 tejbeer 269
 
34342 ranu 270
    static Map<Double, List<ScratchedGift>> GIFT_SERIES = new TreeMap<>(Comparator.reverseOrder());
271
    private final Map<Integer, LocalDate> partnerNeckbandTracking = new HashMap<>();
272
 
34340 ranu 273
    // Define eligible partners for LED & Microwave Oven
274
    private static final Set<Integer> PREMIUM_ELIGIBLE_PARTNERS = new HashSet<>(Arrays.asList(175139287, 159690067));
34342 ranu 275
    private static Map<ScratchedGift, Integer> GIFT_QUANTITIES = new HashMap<>();
276
    private final Map<ScratchedGift, LocalDate> premiumGiftTracking = new HashMap<>();
277
    List<Double> PRICE_RANGE = Arrays.asList(0.0, Double.MAX_VALUE);
33899 ranu 278
 
34340 ranu 279
    static {
280
        GIFT_QUANTITIES.put(ScratchedGift.ACCESSORIES_50_PERCENT_OFF, 500);
281
        GIFT_QUANTITIES.put(ScratchedGift.NECK_BAND, 280);
282
        GIFT_QUANTITIES.put(ScratchedGift.LED, 1);
283
        GIFT_QUANTITIES.put(ScratchedGift.MICROWAVE_OVEN, 1);
284
    }
285
 
286
    static {
287
        GIFT_SERIES.put(0.0, Arrays.asList(ScratchedGift.ACCESSORIES_50_PERCENT_OFF, ScratchedGift.NECK_BAND));
288
        GIFT_SERIES.put(50001.0, Arrays.asList(ScratchedGift.ACCESSORIES_50_PERCENT_OFF, ScratchedGift.NECK_BAND, ScratchedGift.MICROWAVE_OVEN, ScratchedGift.LED));
289
    }
290
 
33899 ranu 291
    private void persistNonSerializedWithCustomSerialNumber(CustomFofoOrderItem customFofoOrderItem, int orderItemId) {
292
        // Create a new instance of FofoNonSerializeSerial
293
        for (String accSerialNumber : customFofoOrderItem.getCustomSerialNumbers()) {
294
            if (!accSerialNumber.isEmpty()) {
295
                FofoNonSerializeSerial nonSerializeSerial = new FofoNonSerializeSerial();
296
 
297
                // Populate the entity with relevant information
298
                nonSerializeSerial.setOrderItemId(orderItemId);
299
                nonSerializeSerial.setSerialNumber(accSerialNumber);
300
 
301
                // Save the entity to the database
302
                fofoNonSerializeSerialRepository.persist(nonSerializeSerial);
303
            }
304
 
305
        }
306
    }
307
 
308
 
309
    public void sendAppDownloadBillingOffer(String mobileNumber) throws Exception {
310
        String sdurl = "http://surl.li/anhfn";
311
        try {
312
            if (prodEnv) {
313
                this.sendSms(APP_DOWNLOAD_BILLING_TEMPLATE_ID, String.format(APP_DOWNLOAD_BILLING_OFFER, sdurl), mobileNumber);
314
            }
315
        } catch (Exception e) {
316
            e.printStackTrace();
317
        }
318
 
319
    }
320
 
321
    public void sendSms(String dltTemplateId, String message, String mobileNumber) throws Exception {
322
        Map<String, String> map = new HashMap<>();
323
 
324
        map.put("sender", SENDER);
325
        map.put("messagetype", "TXT");
326
        map.put("apikey", "b866f7-c6c483-682ff5-054420-ad9e2c");
327
 
328
        map.put("numbers", "91" + mobileNumber);
329
        LOGGER.info("Message {}", message);
330
        // OTP Message Template
331
        map.put("message", message);
332
        map.put("dlttempid", dltTemplateId);
333
 
334
        String response = restClient.post(SMS_GATEWAY, map, new HashMap<>());
335
        LOGGER.info(response);
336
 
337
    }
338
 
339
 
340
    private void createScratchOffer(int fofoId, String invoiceNumber, int customerId) {
341
 
342
        //ScratchedGift gift = getScratchedGiftRandom(fofoId, customerId);
343
 
344
 
345
        //  LocalDateTime endDate = LocalDateTime.of(LocalDate.now().getYear(), LocalDate.now().getMonth(), 27, 21, 00);
346
        List<ScratchOffer> scratchOffers = scratchOfferRepository.selectBycCustomerIdAndDate(customerId, ProfitMandiConstants.SCRATCH_OFFER_START_DATE, ProfitMandiConstants.SCRATCH_OFFER_END_DATE);
347
        if (scratchOffers.size() == 0) {
348
            ScratchOffer so2 = new ScratchOffer();
349
            so2.setInvoiceNumber(invoiceNumber);
350
            so2.setScratched(false);
351
            so2.setCreatedTimestamp(LocalDateTime.now());
352
            so2.setExpiredTimestamp(ProfitMandiConstants.SCRATCH_OFFER_END_DATE.plusDays(1).atTime(LocalTime.MAX));
353
            so2.setOfferName(ScratchedGift.BLNT);
354
            so2.setCustomerId(customerId);
355
 
356
            LocalDateTime today830PM = LocalDate.now().atTime(20, 30);
357
            LocalDateTime today9PM = LocalDate.now().atTime(21, 0);
358
            so2.setUnlockedAt(LocalDateTime.now());
359
 
360
//            if (LocalDateTime.now().isAfter(today830PM)) {
361
//                so2.setUnlockedAt(today9PM.plusDays(0));
362
//            } else {
363
//                so2.setUnlockedAt(today9PM);
364
//            }
365
            scratchOfferRepository.persist(so2);
366
        }
367
    }
368
 
34341 ranu 369
 
32145 tejbeer 370
    @Override
34194 ranu 371
    public int createOrder(CreateOrderRequest createOrderRequest, int fofoId, boolean accessoriesDeals) throws Exception {
32145 tejbeer 372
        LOGGER.info("fofoId -- {} Order Request -- {}", fofoId, createOrderRequest);
373
        CustomCustomer customCustomer = createOrderRequest.getCustomer();
374
        Customer customer = customerRepository.selectById(customCustomer.getCustomerId());
22872 ashik.ali 375
 
32145 tejbeer 376
        if (!StringUtils.isValidGstNumber(customCustomer.getGstNumber())) {
377
            LOGGER.error("invalid customer gstNumber {} ", customCustomer.getGstNumber());
378
            throw new ProfitMandiBusinessException(ProfitMandiConstants.CUSTOMER_GST_NUMBER, customCustomer.getGstNumber(), "VE_1072");
379
        }
23650 amit.gupta 380
 
32145 tejbeer 381
        Map<Integer, Integer> itemIdQuantity = new HashMap<>(); // this is for error
382
        Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap = new HashMap<>();
383
        Map<Integer, Float> lineItemPrice = new HashMap<>(); // this is for pricing error
23650 amit.gupta 384
 
32145 tejbeer 385
        float totalAmount = 0;
386
        boolean noGST = false;
33520 amit.gupta 387
        int changedTotalBillAmount = 0;
388
        for (CustomPaymentOption cpo : createOrderRequest.getPaymentOptions()) {
33399 ranu 389
            changedTotalBillAmount += cpo.getAmount();
390
        }
32145 tejbeer 391
        for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
33520 amit.gupta 392
            if (customFofoOrderItem.getPoiId() > 0) {
33399 ranu 393
                PendingOrderItem pendingOrderItem = pendingOrderItemRepository.selectById(customFofoOrderItem.getPoiId());
33520 amit.gupta 394
                if (customFofoOrderItem.getQuantity() > pendingOrderItem.getQuantity()) {
33414 amit.gupta 395
                    throw new ProfitMandiBusinessException("itemIdQuantity", customFofoOrderItem.getItemId(), "Quantity should not be greater than order item quantity");
33399 ranu 396
                }
33520 amit.gupta 397
                if (pendingOrderItem.getQuantity() > customFofoOrderItem.getQuantity()) {
398
                    pendingOrderService.duplicatePendingOrder(pendingOrderItem, customFofoOrderItem.getQuantity());
33399 ranu 399
                }
400
            }
32145 tejbeer 401
            // itemIds.add(customFofoOrderItem.getItemId());
402
            Set<String> serialNumbers = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());
403
            if (!serialNumbers.isEmpty() && customFofoOrderItem.getQuantity() != serialNumbers.size()) {
404
                itemIdQuantity.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
405
            }
406
            if (!(customFofoOrderItem.getSellingPrice() > 0)) {
407
                lineItemPrice.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getSellingPrice());
408
            } else {
33554 tejus.loha 409
                totalAmount = totalAmount + customFofoOrderItem.getSellingPrice() * customFofoOrderItem.getQuantity();
32145 tejbeer 410
                for (SerialNumberDetail serialNumberDetail : customFofoOrderItem.getSerialNumberDetails()) {
411
                    if (serialNumberDetail.getAmount() > 0) {
412
                        totalAmount = totalAmount + serialNumberDetail.getAmount();
413
                    }
414
                }
415
            }
23650 amit.gupta 416
 
32145 tejbeer 417
            itemIdCustomFofoOrderItemMap.put(customFofoOrderItem.getItemId(), customFofoOrderItem);
418
        }
419
        if (!itemIdQuantity.isEmpty()) {
420
            // if item quantity does not match with given serialnumbers size
421
            LOGGER.error("itemId's quantity should be equal to given serialnumber size {} ", itemIdQuantity);
422
            throw new ProfitMandiBusinessException("itemIdQuantity", itemIdQuantity, "FFORDR_1001");
423
            // return "error";
424
        }
23650 amit.gupta 425
 
32145 tejbeer 426
        this.validatePaymentOptionsAndTotalAmount(createOrderRequest.getPaymentOptions(), totalAmount);
23650 amit.gupta 427
 
32145 tejbeer 428
        if (!lineItemPrice.isEmpty()) {
429
            // given fofo line item price must be greater than zero
430
            LOGGER.error("requested itemId's selling price must greater than 0");
431
            throw new ProfitMandiBusinessException(ProfitMandiConstants.PRICE, lineItemPrice, "FFORDR_1002");
432
        }
22859 ashik.ali 433
 
32145 tejbeer 434
        List<CurrentInventorySnapshot> currentInventorySnapshots = currentInventorySnapshotRepository.selectByFofoItemIds(fofoId, itemIdCustomFofoOrderItemMap.keySet());
23650 amit.gupta 435
 
32145 tejbeer 436
        this.validateCurrentInventorySnapshotQuantities(currentInventorySnapshots, itemIdCustomFofoOrderItemMap);
22859 ashik.ali 437
 
32145 tejbeer 438
        List<Item> items = itemRepository.selectByIds(itemIdCustomFofoOrderItemMap.keySet());
439
        if (items.size() != itemIdCustomFofoOrderItemMap.keySet().size()) {
440
            LOGGER.error("Requested ItemIds not found in catalog");
441
            // invalid itemIds
442
            throw new ProfitMandiBusinessException("invalidItemIds", itemIdCustomFofoOrderItemMap.keySet(), "FFORDR_1003");
443
        }
23650 amit.gupta 444
 
32145 tejbeer 445
        Map<Integer, Item> itemMap = this.toItemMap(items);
23650 amit.gupta 446
 
32145 tejbeer 447
        Set<Integer> nonSerializedItemIds = new HashSet<>();
448
        Set<String> serialNumbers = new HashSet<>();
449
        List<InsuranceModel> insuredModels = new ArrayList<>();
450
        for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
451
            Item item = itemMap.get(customFofoOrderItem.getItemId());
452
            noGST = item.getHsnCode().equals("NOGST");
453
            if (item.getType().equals(ItemType.SERIALIZED)) {
454
                for (SerialNumberDetail serialNumberDetail : customFofoOrderItem.getSerialNumberDetails()) {
455
                    serialNumbers.add(serialNumberDetail.getSerialNumber());
456
                    if (serialNumberDetail.getAmount() > 0) {
457
                        if (customer.getEmailId() == null || customer.getEmailId().equals("")) {
458
                            throw new ProfitMandiBusinessException("Email Id is required for insurance", "Email Id is required for insurance", "Email Id is required for insurance");
459
                        }
34194 ranu 460
 
32145 tejbeer 461
                        InsuranceModel im = new InsuranceModel();
462
                        im.setBrand(item.getBrand());
463
                        im.setColor(item.getColor());
464
                        im.setModelName(item.getModelName() + item.getModelNumber());
465
                        im.setInsuranceAmount(serialNumberDetail.getAmount());
466
                        im.setDeviceSellingPrice(customFofoOrderItem.getSellingPrice());
34194 ranu 467
                        im.setInsuranceUId(serialNumberDetail.getInsurance());
468
                        im.setInsuranceId(String.valueOf(insuranceService.getOneAssistPremiumByVariantId(serialNumberDetail.getInsurance()).getId()));
32145 tejbeer 469
                        im.setSerialNumber(serialNumberDetail.getSerialNumber());
470
                        im.setMemory(serialNumberDetail.getMemory());
471
                        im.setRam(serialNumberDetail.getRam());
472
                        im.setMfgDate(serialNumberDetail.getMfgDate());
473
                        insuredModels.add(im);
474
                        // Check for free insurance code
475
                        try {
33520 amit.gupta 476
                            Map<String, List<MobileInsurancePlan>> mobileInsurancePlanMap = insuranceService.getAllPlans(item.getId(), im.getDeviceSellingPrice(), false);
32145 tejbeer 477
                            MobileInsurancePlan mobileInsurancePlan = mobileInsurancePlanMap.entrySet().stream().flatMap(x -> x.getValue().stream()).filter(x -> x.getProductId().equals(serialNumberDetail.getInsurance())).findFirst().get();
478
                            if (mobileInsurancePlan.getPlanName().equals("OneAssist Damage Protection Plan")) {
479
                                MobileInsurancePlan freePlan = mobileInsurancePlanMap.get("Prolong Extendended Warranty(SmartDukaan Special Price)").get(0);
480
                                InsuranceModel imFree = new InsuranceModel();
481
                                imFree.setBrand(item.getBrand());
482
                                imFree.setColor(item.getColor());
483
                                imFree.setModelName(item.getModelName() + item.getModelNumber());
484
                                imFree.setInsuranceAmount(0);
485
                                imFree.setDeviceSellingPrice(customFofoOrderItem.getSellingPrice());
34207 ranu 486
                                LOGGER.info("freePlan.getProductId() {}", freePlan.getProductId());
487
                                imFree.setInsuranceUId(freePlan.getProductId());
488
                                imFree.setInsuranceId(String.valueOf(insuranceService.getOneAssistPremiumByVariantId(freePlan.getProductId()).getId()));
32145 tejbeer 489
                                imFree.setSerialNumber(serialNumberDetail.getSerialNumber());
490
                                imFree.setMemory(serialNumberDetail.getMemory());
491
                                imFree.setRam(serialNumberDetail.getRam());
492
                                imFree.setMfgDate(serialNumberDetail.getMfgDate());
493
                                insuredModels.add(imFree);
494
                            }
495
                        } catch (Exception e) {
496
                            LOGGER.error("Exception - {}", e);
497
                            throw new ProfitMandiBusinessException("problem fetching plans", "problem fetching plans", "problem fetching plans");
498
                        }
499
                    }
31274 amit.gupta 500
 
32145 tejbeer 501
                }
502
            } else {
503
                nonSerializedItemIds.add(customFofoOrderItem.getItemId());
504
            }
505
        }
23650 amit.gupta 506
 
32145 tejbeer 507
        Map<Integer, Set<InventoryItem>> serializedInventoryItemMap = new HashMap<>();
508
        Map<Integer, Set<InventoryItem>> nonSerializedInventoryItemMap = new HashMap<>();
509
        // Map<String, Float> serialNumberItemPrice = new HashMap<>();
23650 amit.gupta 510
 
32145 tejbeer 511
        if (!serialNumbers.isEmpty()) {
512
            List<InventoryItem> serializedInventoryItems = inventoryItemRepository.selectByFofoIdSerialNumbers(fofoId, serialNumbers, false);
513
            LOGGER.info("serializedInventoryItems {}", serializedInventoryItems);
514
            for (InventoryItem inventoryItem : serializedInventoryItems) {
515
                if (inventoryItem.getGoodQuantity() == 1) {
516
                    if (serializedInventoryItemMap.containsKey(inventoryItem.getItemId())) {
517
                        serializedInventoryItemMap.get(inventoryItem.getItemId()).add(inventoryItem);
518
                    } else {
519
                        Set<InventoryItem> itemIdInventoryItems = new HashSet<>();
520
                        itemIdInventoryItems.add(inventoryItem);
521
                        serializedInventoryItemMap.put(inventoryItem.getItemId(), itemIdInventoryItems);
522
                    }
523
                }
524
            }
525
        }
23418 ashik.ali 526
 
32145 tejbeer 527
        if (!nonSerializedItemIds.isEmpty()) {
528
            List<InventoryItem> nonSerializedInventoryItems = inventoryItemRepository.selectByFofoIdItemIds(fofoId, nonSerializedItemIds);
529
            LOGGER.info("nonSerializedInventoryItems {}", nonSerializedInventoryItems);
530
            for (InventoryItem it : nonSerializedInventoryItems) {
531
                if (it.getGoodQuantity() > 0) {
532
                    if (nonSerializedInventoryItemMap.containsKey(it.getItemId())) {
533
                        nonSerializedInventoryItemMap.get(it.getItemId()).add(it);
534
                    } else {
535
                        Set<InventoryItem> tmp = new HashSet<>();
536
                        tmp.add(it);
537
                        nonSerializedInventoryItemMap.put(it.getItemId(), tmp);
538
                    }
539
                }
540
            }
541
        }
23650 amit.gupta 542
 
32145 tejbeer 543
        this.validateItemsSerializedNonSerialized(items, itemIdCustomFofoOrderItemMap);
22859 ashik.ali 544
 
32145 tejbeer 545
        Map<Integer, Set<InventoryItem>> inventoryItemsToBill = new HashMap<>();
546
        Map<Integer, Integer> inventoryItemIdQuantityUsed = new HashMap<>(); // to keep track of inventoryitem quanity
547
        // used for scan records insertion
22859 ashik.ali 548
 
32145 tejbeer 549
        LOGGER.info("itemMap keys {}", itemMap.keySet());
550
        // Lets reduce quantity and decide what inventory items to use.
551
        for (Item item : items) {
552
            if (item.getType().equals(ItemType.SERIALIZED)) {
553
                // TODO:handle null
554
                if (serializedInventoryItemMap.get(item.getId()) == null || itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().size() != serializedInventoryItemMap.get(item.getId()).size()) {
24440 amit.gupta 555
 
32145 tejbeer 556
                    List<String> invalidSerialNumbers = itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());
557
                    throw new ProfitMandiBusinessException("invalidSerialNumbers", invalidSerialNumbers, "FFORDR_1004");
558
                }
559
                List<String> serialNumberList = liveDemoBillingRespository.selectAllSerialNumber();
24823 amit.gupta 560
 
32145 tejbeer 561
                Set<InventoryItem> inventoryItemsSerializedserialized = serializedInventoryItemMap.get(item.getId());
562
                for (InventoryItem inventoryItem : inventoryItemsSerializedserialized) {
563
                    inventoryItem.setGoodQuantity(0);
564
                    inventoryItemIdQuantityUsed.put(inventoryItem.getId(), 1);
565
                    if (serialNumberList.contains(inventoryItem.getSerialNumber())) {
566
                        LiveDemoSerialNumber liveDemoSerialNumber = liveDemoBillingRespository.selectBySerialNumber(inventoryItem.getSerialNumber());
567
                        liveDemoBillingRespository.delete(liveDemoSerialNumber);
568
                    }
569
                }
570
                inventoryItemsToBill.put(item.getId(), inventoryItemsSerializedserialized);
571
            } else {
572
                Set<InventoryItem> inventoryItemsNonSerialized = nonSerializedInventoryItemMap.get(item.getId());
573
                int quantityToBill = itemIdCustomFofoOrderItemMap.get(item.getId()).getQuantity();
574
                int totalLeft = quantityToBill;
575
                Set<InventoryItem> inventoryItemsNonSerializedUsed = new HashSet<>();
576
                if (inventoryItemsNonSerialized != null) {
577
                    for (InventoryItem inventoryItem : inventoryItemsNonSerialized) {
578
                        if (totalLeft > 0) {
579
                            int toUse = Math.min(totalLeft, inventoryItem.getGoodQuantity());
580
                            inventoryItemIdQuantityUsed.put(inventoryItem.getId(), toUse);
581
                            inventoryItem.setGoodQuantity(inventoryItem.getGoodQuantity() - toUse);
582
                            totalLeft = totalLeft - toUse;
583
                            inventoryItemsNonSerializedUsed.add(inventoryItem);
584
                        }
585
                    }
586
                }
23650 amit.gupta 587
 
32145 tejbeer 588
                if (totalLeft > 0) {
589
                    // not enough quanity for non-serialized
590
                    LOGGER.error("not enough quanity for non-serialized");
591
                    throw new ProfitMandiBusinessException("notEnoughQuantityForNonSerialized", totalLeft, "FFORDR_1005");
592
                }
593
                inventoryItemsToBill.put(item.getId(), inventoryItemsNonSerializedUsed);
594
            }
595
        }
23650 amit.gupta 596
 
32145 tejbeer 597
        Map<Integer, PriceModel> itemIdMopPriceMap = pricingService.getPurchasePriceMopPriceNotFound(itemIdCustomFofoOrderItemMap.keySet(), fofoId);
598
        LOGGER.info("itemIdMopMap {}", itemIdMopPriceMap);
599
        if (accessoriesDeals) {
32420 amit.gupta 600
            this.validateDpPrice(fofoId, itemIdMopPriceMap, itemIdCustomFofoOrderItemMap);
32145 tejbeer 601
        } else {
32420 amit.gupta 602
            this.validateMopPrice(fofoId, itemIdMopPriceMap, itemIdCustomFofoOrderItemMap);
32145 tejbeer 603
        }
23650 amit.gupta 604
 
32145 tejbeer 605
        String fofoStoreCode = this.getFofoStoreCode(fofoId);
606
        String documentNumber = null;
607
        if (noGST) {
608
            documentNumber = this.getSecurityDepositNumber(fofoId, fofoStoreCode);
24275 amit.gupta 609
 
32145 tejbeer 610
        } else {
611
            documentNumber = this.getInvoiceNumber(fofoId, fofoStoreCode);
612
        }
22859 ashik.ali 613
 
32627 ranu 614
        CustomerAddress customerAddress = null;
615
        if (customCustomer.getCustomerAddressId() != 0) {
616
            customerAddress = customer.getCustomerAddress().stream().filter(x -> x.getId() == customCustomer.getCustomerAddressId()).findFirst().get();
617
        }
34319 amit.gupta 618
        FofoOrder fofoOrder = this.createAndGetFofoOrder(customer.getId(), customCustomer.getGstNumber(), fofoId, documentNumber, totalAmount, customCustomer.getCustomerAddressId());
23650 amit.gupta 619
 
32145 tejbeer 620
        this.createPaymentOptions(fofoOrder, createOrderRequest.getPaymentOptions());
23650 amit.gupta 621
 
32145 tejbeer 622
        int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoId);
23650 amit.gupta 623
 
32145 tejbeer 624
        Address retailerAddress = addressRepository.selectById(retailerAddressId);
23650 amit.gupta 625
 
32145 tejbeer 626
        Integer stateId = null;
32634 amit.gupta 627
        if (customerAddress == null || customerAddress.getState() == null || customerAddress.getState().equals(retailerAddress.getState())) {
32145 tejbeer 628
            try {
32634 amit.gupta 629
                State state = stateRepository.selectByName(retailerAddress.getState());
32145 tejbeer 630
                stateId = Long.valueOf(state.getId()).intValue();
631
            } catch (Exception e) {
632
                LOGGER.error("Unable to get state rates");
633
            }
634
        }
23650 amit.gupta 635
 
32145 tejbeer 636
        for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
637
            FofoOrderItem fofoOrderItem = this.createAndGetFofoOrderItem(customFofoOrderItem, fofoOrder.getId(), itemMap, inventoryItemsToBill.get(customFofoOrderItem.getItemId()), stateId);
23650 amit.gupta 638
 
32816 ranu 639
            Item item = itemMap.get(customFofoOrderItem.getItemId());
640
            if (item.getType().equals(ItemType.NON_SERIALIZED)) {
641
                if (customFofoOrderItem.getCustomSerialNumbers() != null && !customFofoOrderItem.getCustomSerialNumbers().isEmpty()) {
642
                    persistNonSerializedWithCustomSerialNumber(customFofoOrderItem, fofoOrderItem.getId());
643
                } else {
644
                    LOGGER.info("Custom serial numbers are empty. Not persisting data.");
645
                }
646
            }
647
 
648
 
32145 tejbeer 649
            Set<InventoryItem> inventoryItems = inventoryItemsToBill.get(customFofoOrderItem.getItemId());
23650 amit.gupta 650
 
32145 tejbeer 651
            this.createFofoLineItem(fofoOrderItem.getId(), inventoryItems, inventoryItemIdQuantityUsed);
23650 amit.gupta 652
 
32145 tejbeer 653
            this.updateCurrentInventorySnapshot(currentInventorySnapshots, fofoId, customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
23650 amit.gupta 654
 
32145 tejbeer 655
            this.updateInventoryItemsAndScanRecord(inventoryItems, fofoId, inventoryItemIdQuantityUsed, fofoOrder.getId());
656
        }
23650 amit.gupta 657
 
32145 tejbeer 658
        List<FofoOrderItem> fofoItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
25647 tejbeer 659
 
32145 tejbeer 660
        boolean smartPhone = false;
32892 ranu 661
        for (FofoOrderItem fofoOrderItem : fofoItems) {
662
            Item item = itemRepository.selectById(fofoOrderItem.getItemId());
663
 
664
            if (item.isSmartPhone()) {
665
                LOGGER.info("fofoItem {}", fofoOrderItem);
32145 tejbeer 666
                smartPhone = true;
667
            }
32892 ranu 668
        }
31172 tejbeer 669
 
32892 ranu 670
        if (!smartPhone) {
671
            LOGGER.warn("No smartphones found in fofoItems.");
32145 tejbeer 672
        }
31172 tejbeer 673
 
32892 ranu 674
 
32145 tejbeer 675
        if (smartPhone) {
676
            this.createAndGetHygieneData(fofoOrder.getId(), fofoOrder.getFofoId());
677
        }
678
        // insurance calculation is insurance flag is enabled
679
        //
680
        if (insuredModels.size() > 0) {
681
            LOGGER.info("Processing insurane for serialNumbers");
682
            LOGGER.info("InsuranceModels {}", insuredModels);
683
            LocalDate customerDateOfBirth = LocalDate.from(createOrderRequest.getCustomer().getDateOfBirth());
684
            fofoOrder.setDateOfBirth(customerDateOfBirth);
685
            for (InsuranceModel insuranceModel : insuredModels) {
34207 ranu 686
                LOGGER.info("G- {}", insuranceModel.getInsuranceId());
687
                LOGGER.info("insuranceModel- {}", insuranceModel);
33715 ranu 688
                insuranceService.createInsurance(fofoOrder, insuranceModel, false);
32145 tejbeer 689
            }
690
        }
28339 tejbeer 691
 
32145 tejbeer 692
        schemeService.processSchemeOut(fofoOrder.getId(), fofoId);
31993 amit.gupta 693
 
32145 tejbeer 694
        if (createOrderRequest.getPoId() != 0) {
695
            PendingOrder po = pendingOrderRepository.selectById(createOrderRequest.getPoId());
696
            po.setBilledAmount(po.getBilledAmount() + totalAmount);
33520 amit.gupta 697
            for (CustomFofoOrderItem cfoi : createOrderRequest.getFofoOrderItems()) {
33399 ranu 698
                PendingOrderItem poi = pendingOrderItemRepository.selectById(cfoi.getPoiId());
699
                poi.setStatus(OrderStatus.BILLED);
700
                poi.setBilledTimestamp(LocalDateTime.now());
701
            }
33436 ranu 702
            po.setStatus(OrderStatus.BILLED);
34319 amit.gupta 703
 
32145 tejbeer 704
        }
32961 amit.gupta 705
        //Process scratch
706
        this.processScratchOffer(fofoOrder);
29515 tejbeer 707
 
33795 ranu 708
//        persist the data of upgrade offer table
709
        for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
710
            if (customFofoOrderItem.getCustomerOfferItemId() > 0) {
711
                UpgradeOffer upgradeOffer = new UpgradeOffer();
712
                upgradeOffer.setOrderId(fofoOrder.getId());
713
                upgradeOffer.setCustomerOfferItemId(customFofoOrderItem.getCustomerOfferItemId());
714
                upgradeOffer.setItemId(customFofoOrderItem.getItemId());
715
 
716
                Set<SerialNumberDetail> serialNumberDetails = customFofoOrderItem.getSerialNumberDetails();
717
 
718
                if (!customFofoOrderItem.getSerialNumberDetails().isEmpty()) {
719
                    String serialNumber = serialNumberDetails.iterator().next().getSerialNumber();
720
                    upgradeOffer.setSerialNumber(serialNumber);
721
 
722
//                Set<String> serialNumbersSet = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());
723
//                LOGGER.info("serialNumbersSet.toString() {}",serialNumbersSet.toString());
724
//                upgradeOffer.setSerialNumber(serialNumbersSet.toString());
725
                } else {
726
                    upgradeOffer.setSerialNumber(null); // Handle case where there is no serial number detail
727
                }
728
                upgradeOffer.setCreatedTimestamp(LocalDateTime.now());
33838 ranu 729
                upgradeOffer.setPaymentStatus(UpgradeOfferPaymentStatus.PENDING);
730
                upgradeOffer.setStatusDescription(UpgradeOfferPaymentStatus.PENDING.getValue());
33795 ranu 731
                upgradeOfferRepository.persist(upgradeOffer);
732
            }
733
        }
734
 
735
//        enable it fo upsell call
33715 ranu 736
        if (smartPhone) {
737
            if (fofoOrder.getId() > 0) {
738
                List<InsurancePolicy> insurancePolicies = insurancePolicyRepository
739
                        .selectByRetailerIdInvoiceNumber(fofoOrder.getInvoiceNumber());
740
                if (insurancePolicies.isEmpty()) {
741
                    List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
742
                    for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
743
                        Item item = itemRepository.selectById(fofoOrderItem.getItemId());
744
                        if (item.isSmartPhone()) {
745
                            UpSaleOrder upSaleOrder = new UpSaleOrder();
746
                            upSaleOrder.setCreatedTimestamp(LocalDateTime.now());
747
                            upSaleOrder.setOrderId(fofoOrder.getId());
33718 ranu 748
                            upSaleOrder.setFofoId(fofoOrder.getFofoId());
33715 ranu 749
                            upSaleOrderRepository.persist(upSaleOrder);
750
                            break; // Exit the loop after persisting the UpSaleOrder for the first smartphone
751
                        }
752
                    }
753
                }
754
            }
755
        }
33674 ranu 756
 
33873 ranu 757
        // Update Partner Opening Stock current qty
33899 ranu 758
        if (fofoOrder.getId() > 0) {
33873 ranu 759
            List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
760
            for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
761
                Item item = itemRepository.selectById(fofoOrderItem.getItemId());
33899 ranu 762
                smartCartService.minusOpeningStock(item.getId(), fofoOrder.getFofoId(), fofoOrderItem.getQuantity());
33873 ranu 763
            }
764
        }
765
 
766
 
32961 amit.gupta 767
        return fofoOrder.getId();
768
    }
769
 
33665 ranu 770
    @Override
771
    public void processScratchOffer(FofoOrder fofoOrder) throws ProfitMandiBusinessException {
772
        boolean isSmartPhonePurchased = false;
773
        float maxPurchaseValue = 0;
774
        List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
775
        for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
776
            Item item = itemRepository.selectById(fofoOrderItem.getItemId());
777
 
778
            if (item.isSmartPhone()) {
779
                LOGGER.info("fofoItem {}", fofoOrderItem);
780
                isSmartPhonePurchased = true;
781
                maxPurchaseValue = Math.max(fofoOrderItem.getSellingPrice(), maxPurchaseValue);
782
 
783
            }
784
        }
785
        LocalDate startDate = ProfitMandiConstants.SCRATCH_OFFER_START_DATE;
786
        LocalDate endDate = ProfitMandiConstants.SCRATCH_OFFER_END_DATE;
787
        boolean specificPriceOffer = ProfitMandiConstants.SPECIFIC_PRICE_OFFER;
788
        boolean randomOffer = ProfitMandiConstants.RANDOM_OFFER;
789
 
790
        if (isSmartPhonePurchased) {
791
 
792
            if (LocalDateTime.now().isAfter(startDate.atStartOfDay()) && LocalDateTime.now().isBefore(endDate.atTime(Utils.MAX_TIME))) {
793
                Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
794
                try {
795
                    this.sendAppDownloadBillingOffer(customer.getMobileNumber());
796
                } catch (Exception e) {
797
                    // TODO Auto-generated catch block
798
                    e.printStackTrace();
799
                }
800
                if (specificPriceOffer) {
33899 ranu 801
                    this.createSpecificPriceScratchOffer(fofoOrder.getInvoiceNumber(), fofoOrder.getCustomerId(), fofoOrder.getFofoId(), maxPurchaseValue);
33665 ranu 802
                } else if (randomOffer) {
803
                    this.createRandomScratchOffer(fofoOrder.getInvoiceNumber(), fofoOrder.getCustomerId());
804
                    LOGGER.info("randomOffer {}", randomOffer);
805
                } else {
806
                    this.createScratchOffer(fofoOrder.getFofoId(), fofoOrder.getInvoiceNumber(), fofoOrder.getCustomerId());
807
                }
808
 
809
            }
810
        }
811
    }
812
 
813
    @Override
33899 ranu 814
    public ScratchedGift getSelectedGift(double purchaseAmount, int fofoId) throws ProfitMandiBusinessException {
33665 ranu 815
        Map<ScratchedGift, Long> scratchOfferCountMap = scratchOfferRepository.countOffersByDateRange(ProfitMandiConstants.SCRATCH_OFFER_START_DATE, ProfitMandiConstants.SCRATCH_OFFER_END_DATE);
33899 ranu 816
        RandomCollection<ScratchedGift> giftRandomCollection = createDynamicGiftSeries(scratchOfferCountMap, purchaseAmount, fofoId);
33665 ranu 817
        if (giftRandomCollection.size() > 0) {
34340 ranu 818
            ScratchedGift selectedGift = giftRandomCollection.next();
819
            // Restrict Neckband per partner per day
820
            if (selectedGift == ScratchedGift.NECK_BAND) {
821
                LocalDate lastGivenDate = partnerNeckbandTracking.get(fofoId);
822
                if (lastGivenDate != null && lastGivenDate.equals(LocalDate.now())) {
823
                    LOGGER.info("Neckband already given today for partner {}", fofoId);
824
                    return ScratchedGift.ACCESSORIES_50_PERCENT_OFF;  // Provide an alternate gift
825
                }
826
                // Update tracking for Neckband distribution
827
                partnerNeckbandTracking.put(fofoId, LocalDate.now());
828
            }
829
 
830
            // Restrict LED & Microwave Oven to eligible partners only
831
            if ((selectedGift == ScratchedGift.LED || selectedGift == ScratchedGift.MICROWAVE_OVEN)) {
832
                if (!PREMIUM_ELIGIBLE_PARTNERS.contains(fofoId)) {
833
                    LOGGER.info("Partner {} not eligible for {}", fofoId, selectedGift);
834
                    return ScratchedGift.ACCESSORIES_50_PERCENT_OFF; // Give alternate gift
835
                }
836
 
837
                // Ensure only one LED and one Microwave Oven per day
838
                LocalDate lastGivenDate = premiumGiftTracking.get(selectedGift);
839
                if (lastGivenDate != null && lastGivenDate.equals(LocalDate.now())) {
840
                    LOGGER.info("{} already given today", selectedGift);
841
                    return ScratchedGift.ACCESSORIES_50_PERCENT_OFF;
842
                }
843
 
844
                // Mark the gift as given today
845
                premiumGiftTracking.put(selectedGift, LocalDate.now());
846
            }
847
 
848
            // Restrict LED & Microwave Oven to eligible partners only
849
            if ((selectedGift == ScratchedGift.LED || selectedGift == ScratchedGift.MICROWAVE_OVEN)) {
850
                if (!PREMIUM_ELIGIBLE_PARTNERS.contains(fofoId)) {
851
                    LOGGER.info("Partner {} not eligible for {}", fofoId, selectedGift);
852
                    return ScratchedGift.ACCESSORIES_50_PERCENT_OFF; // Give alternate gift
853
                }
854
 
855
                // Ensure only one LED and one Microwave Oven per day
856
                LocalDate lastGivenDate = premiumGiftTracking.get(selectedGift);
857
                if (lastGivenDate != null && lastGivenDate.equals(LocalDate.now())) {
858
                    LOGGER.info("{} already given today", selectedGift);
859
                    return ScratchedGift.ACCESSORIES_50_PERCENT_OFF;
860
                }
861
 
862
                // Mark the gift as given today
863
                premiumGiftTracking.put(selectedGift, LocalDate.now());
864
            }
865
 
866
            return selectedGift;
33674 ranu 867
        } else {
33895 ranu 868
            return ScratchedGift.ACCESSORIES_50_PERCENT_OFF;
33665 ranu 869
        }
870
    }
871
 
34340 ranu 872
    public RandomCollection<ScratchedGift> createDynamicGiftSeries(Map<ScratchedGift, Long> soldGiftCountMap,
873
                                                                   Double sellingPrice, int fofoId)
874
            throws ProfitMandiBusinessException {
875
 
33665 ranu 876
        int index = 0;
877
        RandomCollection<ScratchedGift> randomCollection = new RandomCollection<>();
33899 ranu 878
        PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(fofoId, LocalDate.now());
879
        LOGGER.info("partnerType {}", partnerType);
880
 
33895 ranu 881
        if (partnerType.equals(PartnerType.BRONZE)) {
33899 ranu 882
            LOGGER.info("partnerType if- {}", partnerType);
33895 ranu 883
            sellingPrice = 0.0;
884
        }
33899 ranu 885
 
886
        for (int i = 0; i < PRICE_RANGE.size(); i++) {
887
            Double price = PRICE_RANGE.get(i);
34340 ranu 888
            Double nextPrice = (i != PRICE_RANGE.size() - 1) ? PRICE_RANGE.get(i + 1) : Double.MAX_VALUE;
889
 
33899 ranu 890
            if (sellingPrice >= price && sellingPrice < nextPrice) {
33665 ranu 891
                int divisor = PRICE_RANGE.size() - index;
33899 ranu 892
                LOGGER.info("Processing price range: {}, sellingPrice: {}", price, sellingPrice);
893
 
33665 ranu 894
                for (ScratchedGift gift : GIFT_SERIES.get(price)) {
34340 ranu 895
                    int remainingQty = GIFT_QUANTITIES.get(gift) - soldGiftCountMap.getOrDefault(gift, 0L).intValue();
33899 ranu 896
                    LOGGER.info("Checking gift: {}, remainingQty: {}", gift, remainingQty);
897
 
33897 ranu 898
                    if (remainingQty > 0) {
899
                        int weight = (remainingQty > divisor) ? remainingQty / divisor : remainingQty;
34340 ranu 900
 
901
                        if (gift == ScratchedGift.NECK_BAND) {
902
                            LocalDate lastGivenDate = partnerNeckbandTracking.get(fofoId);
903
                            if (lastGivenDate == null || !lastGivenDate.equals(LocalDate.now())) {
904
                                randomCollection.add(weight, gift);
905
                            }
906
                        } else if (gift == ScratchedGift.LED || gift == ScratchedGift.MICROWAVE_OVEN) {
907
                            if (PREMIUM_ELIGIBLE_PARTNERS.contains(fofoId) && !premiumGiftTracking.containsKey(gift)) {
908
                                randomCollection.add(weight, gift);
909
                            }
910
                        } else {
911
                            randomCollection.add(weight, gift);
912
                        }
33665 ranu 913
                    }
914
                }
34340 ranu 915
                break;
33665 ranu 916
            }
33897 ranu 917
            index++;
33665 ranu 918
        }
33899 ranu 919
 
920
        if (randomCollection.size() == 0) {
921
            LOGGER.info("No gifts added for sellingPrice: {} in createDynamicGiftSeries", sellingPrice);
922
        }
923
 
33665 ranu 924
        return randomCollection;
925
    }
926
 
33899 ranu 927
 
928
 
33665 ranu 929
    /*static {
32960 amit.gupta 930
        RandomCollection<ScratchedGift> map1 = new RandomCollection<ScratchedGift>().
931
                add(100d, ScratchedGift.GIFT_BOWL);
932
        GIFT_SERIES.put(0.0, map1);
933
        //Map<ScratchedGift, Double> map2 = new HashMap<>();
934
        RandomCollection<ScratchedGift> map2 = new RandomCollection<ScratchedGift>()
935
                .add(40d, ScratchedGift.GIFT_BOWL)
936
                .add(20d, ScratchedGift.NECK_BAND)
937
                .add(30d, ScratchedGift.FLASKNMUG)
938
                .add(10d, ScratchedGift.ELECTRIC_KETTLE);
939
        GIFT_SERIES.put(10001.0, map2);
940
        RandomCollection<ScratchedGift> map3 = new RandomCollection<ScratchedGift>()
941
                .add(25d, ScratchedGift.GIFT_BOWL)
942
                .add(30d, ScratchedGift.NECK_BAND)
943
                .add(10d, ScratchedGift.SPEAKER)
944
                .add(25d, ScratchedGift.FLASKNMUG)
945
                .add(10d, ScratchedGift.ELECTRIC_KETTLE);
946
        GIFT_SERIES.put(18001.0, map3);
947
        RandomCollection<ScratchedGift> map4 = new RandomCollection<ScratchedGift>()
948
                .add(30d, ScratchedGift.NECK_BAND)
949
                .add(20d, ScratchedGift.SPEAKER)
950
                .add(20d, ScratchedGift.FLASKNMUG)
951
                .add(30d, ScratchedGift.ELECTRIC_KETTLE);
952
        GIFT_SERIES.put(25001.0, map4);
953
        RandomCollection<ScratchedGift> map5 = new RandomCollection<ScratchedGift>()
954
                .add(40d, ScratchedGift.SPEAKER)
955
                .add(60d, ScratchedGift.SMART_WATCH);
32892 ranu 956
 
32960 amit.gupta 957
        GIFT_SERIES.put(50001.0, map5);
33665 ranu 958
    }*/
32892 ranu 959
 
32960 amit.gupta 960
 
33895 ranu 961
    private void createSpecificPriceScratchOffer(String invoiceNumber, int customerId, int fofoId, float purchaseAmount) throws ProfitMandiBusinessException {
33899 ranu 962
        ScratchedGift selectedGift = getSelectedGift(purchaseAmount, fofoId);
33142 ranu 963
        List<ScratchOffer> scratchOffers = scratchOfferRepository.selectBycCustomerIdAndDate(customerId, ProfitMandiConstants.SCRATCH_OFFER_START_DATE, ProfitMandiConstants.SCRATCH_OFFER_END_DATE);
964
        if (scratchOffers.size() == 0) {
965
            ScratchOffer so2 = new ScratchOffer();
966
            so2.setInvoiceNumber(invoiceNumber);
967
            so2.setScratched(false);
968
            so2.setCreatedTimestamp(LocalDateTime.now());
33679 ranu 969
            so2.setExpiredTimestamp(ProfitMandiConstants.SCRATCH_OFFER_END_DATE.plusDays(1).atTime(LocalTime.MAX));
33142 ranu 970
            so2.setOfferName(selectedGift);
971
            so2.setCustomerId(customerId);
972
            so2.setUnlockedAt(LocalDateTime.now());
973
            scratchOfferRepository.persist(so2);
974
        }
975
    }
32960 amit.gupta 976
 
33142 ranu 977
    private void createRandomScratchOffer(String invoiceNumber, int customerId) {
978
        ScratchedGift selectedGift = getScratchedGiftRandomAccordingQuantity(customerId);
32892 ranu 979
        List<ScratchOffer> scratchOffers = scratchOfferRepository.selectBycCustomerIdAndDate(customerId, ProfitMandiConstants.SCRATCH_OFFER_START_DATE, ProfitMandiConstants.SCRATCH_OFFER_END_DATE);
980
        if (scratchOffers.size() == 0) {
981
            ScratchOffer so2 = new ScratchOffer();
982
            so2.setInvoiceNumber(invoiceNumber);
983
            so2.setScratched(false);
984
            so2.setCreatedTimestamp(LocalDateTime.now());
33679 ranu 985
            so2.setExpiredTimestamp(ProfitMandiConstants.SCRATCH_OFFER_END_DATE.plusDays(1).atTime(LocalTime.MAX));
32892 ranu 986
            so2.setOfferName(selectedGift);
987
            so2.setCustomerId(customerId);
988
            so2.setUnlockedAt(LocalDateTime.now());
989
            scratchOfferRepository.persist(so2);
990
        }
991
    }
992
 
33247 ranu 993
    private ScratchedGift getScratchedGiftRandom(int fofoId, int customerId) throws ProfitMandiBusinessException {
32218 tejbeer 994
        Map<Integer, ScratchedGift> giftSeries = new HashMap<>();
995
        giftSeries.put(1, ScratchedGift.MINI_CHOPPER);
996
        giftSeries.put(2, ScratchedGift.FRUIT_JUICER);
997
        giftSeries.put(3, ScratchedGift.STEAM_IRON);
998
 
999
 
32579 amit.gupta 1000
        List<FofoOrder> fofoOrders = fofoOrderRepository.selectByFofoIdBetweenCreatedTimeStamp(fofoId, ProfitMandiConstants.SCRATCH_OFFER_START_DATE.atStartOfDay(),
1001
                ProfitMandiConstants.SCRATCH_OFFER_END_DATE.atTime(Utils.MAX_TIME));
32218 tejbeer 1002
 
1003
        ScratchedGift gift = ScratchedGift.BLNT;
1004
 
1005
        Random random = new Random();
32672 amit.gupta 1006
        int rand;
32218 tejbeer 1007
        while (true) {
1008
            rand = random.nextInt(4);
1009
            if (rand != 0) break;
1010
        }
1011
        if (fofoOrders.isEmpty()) {
1012
            gift = giftSeries.get(rand);
1013
        } else {
1014
 
1015
            List<String> invoiceNumbers = fofoOrders.stream().filter(x -> x.getCancelledTimestamp() == null).map(x -> x.getInvoiceNumber()).collect(Collectors.toList());
1016
 
1017
            List<ScratchOffer> scratchOffers = scratchOfferRepository.selectByInvoiceNumbers(invoiceNumbers);
1018
            if (scratchOffers.isEmpty()) {
1019
                gift = giftSeries.get(rand);
1020
            } else {
1021
                List<ScratchOffer> bigGifts = scratchOffers.stream().filter(x -> !x.getOfferName().equals(ScratchedGift.BLNT) && !x.getOfferName().equals(ScratchedGift.EW)).collect(Collectors.toList());
1022
                if (bigGifts.size() <= 10) {
1023
                    List<Integer> scratchCustomerIds = scratchOffers.stream().map(x -> x.getCustomerId()).collect(Collectors.toList());
1024
                    if (scratchCustomerIds.contains(customerId)) {
1025
 
1026
 
1027
                        gift = ScratchedGift.BLNT;
1028
 
1029
                        LOGGER.info("gift2 {}", gift);
1030
 
1031
                    } else {
1032
 
1033
                        int miniChopper = (int) bigGifts.stream().filter(x -> x.getOfferName().equals(ScratchedGift.MINI_CHOPPER)).count();
1034
                        int fruitJuicer = (int) bigGifts.stream().filter(x -> x.getOfferName().equals(ScratchedGift.FRUIT_JUICER)).count();
1035
                        int streanIron = (int) bigGifts.stream().filter(x -> x.getOfferName().equals(ScratchedGift.STEAM_IRON)).count();
1036
 
1037
                        if (rand == 1) {
1038
                            if (miniChopper < 4) {
1039
                                LOGGER.info("miniChopper {}", miniChopper);
1040
 
1041
 
1042
                                gift = giftSeries.get(rand);
1043
                            }
1044
                        }
1045
 
1046
                        if (rand == 2) {
1047
                            if (fruitJuicer < 3) {
1048
 
1049
                                LOGGER.info("fruitJuicer {}", fruitJuicer);
1050
 
1051
                                gift = giftSeries.get(rand);
1052
                            }
1053
                        }
1054
 
1055
                        if (rand == 3) {
1056
                            if (streanIron < 3) {
1057
 
1058
                                LOGGER.info("streanIron {}", streanIron);
1059
 
1060
 
1061
                                gift = giftSeries.get(rand);
1062
 
1063
                            }
1064
                        }
1065
 
1066
                        LOGGER.info("gift4 {}", gift);
1067
                    }
1068
                }
1069
            }
1070
 
1071
 
1072
        }
32586 ranu 1073
        return gift;
32145 tejbeer 1074
    }
29515 tejbeer 1075
 
33142 ranu 1076
    private ScratchedGift getScratchedGiftRandomAccordingQuantity(int customerId) {
1077
        RandomCollection<ScratchedGift> map1 = new RandomCollection<ScratchedGift>().
1078
                add(50d, ScratchedGift.SOLOR_LAMP)
1079
                .add(100d, ScratchedGift.BLUETOOTH_SPEAKER)
1080
                .add(150d, ScratchedGift.RED_WATER_BOTTLE)
1081
                .add(200d, ScratchedGift.GIFT_BOWL)
1082
                .add(100d, ScratchedGift.EARBUDS);
1083
 
33665 ranu 1084
        ScratchedGift gift;
33142 ranu 1085
 
33665 ranu 1086
        List<ScratchOffer> lastScratchOffers = scratchOfferRepository.selectBycCustomerIdAndDate(customerId, ProfitMandiConstants.LAST_SCRATCH_OFFER_START_DATE, ProfitMandiConstants.LAST_SCRATCH_OFFER_END_DATE);
1087
 
1088
        if (lastScratchOffers.isEmpty()) {
1089
            gift = map1.next();
1090
        } else {
1091
            gift = ScratchedGift.RED_WATER_BOTTLE;
1092
            LOGGER.info("RED_WATER_BOTTLE {}", gift);
33142 ranu 1093
        }
1094
        return gift;
1095
    }
1096
 
32145 tejbeer 1097
    private HygieneData createAndGetHygieneData(int id, int fofoId) {
1098
        HygieneData hygieneData = new HygieneData();
1099
        hygieneData.setOrderId(id);
1100
        hygieneData.setFofoId(fofoId);
1101
        hygieneData.setCreatedTimestamp(LocalDateTime.now());
1102
        hygieneDataRepository.persist(hygieneData);
25640 tejbeer 1103
 
32145 tejbeer 1104
        return hygieneData;
1105
    }
25640 tejbeer 1106
 
33665 ranu 1107
 
32145 tejbeer 1108
    @Override
1109
    public String getInvoiceNumber(int fofoId, String fofoStoreCode) {
1110
        InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;
1111
        try {
1112
            invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);
1113
            invoiceNumberGenerationSequence.setSequence(invoiceNumberGenerationSequence.getSequence() + 1);
1114
        } catch (ProfitMandiBusinessException profitMandiBusinessException) {
1115
            invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();
1116
            invoiceNumberGenerationSequence.setFofoId(fofoId);
1117
            invoiceNumberGenerationSequence.setPrefix(fofoStoreCode);
1118
            invoiceNumberGenerationSequence.setSequence(1);
1119
        }
1120
        invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);
1121
        return invoiceNumberGenerationSequence.getPrefix() + "/" + invoiceNumberGenerationSequence.getSequence();
1122
    }
24275 amit.gupta 1123
 
32145 tejbeer 1124
    private String getSecurityDepositNumber(int fofoId, String fofoStoreCode) {
1125
        InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;
1126
        try {
1127
            invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);
1128
            invoiceNumberGenerationSequence.setChallanNumberSequence(invoiceNumberGenerationSequence.getChallanNumberSequence() + 1);
1129
        } catch (ProfitMandiBusinessException profitMandiBusinessException) {
1130
            invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();
1131
            invoiceNumberGenerationSequence.setFofoId(fofoId);
1132
            invoiceNumberGenerationSequence.setPrefix(fofoStoreCode);
1133
            invoiceNumberGenerationSequence.setChallanNumberSequence(1);
1134
        }
1135
        invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);
1136
        return invoiceNumberGenerationSequence.getPrefix() + "/SEC" + invoiceNumberGenerationSequence.getChallanNumberSequence();
1137
    }
24226 amit.gupta 1138
 
32145 tejbeer 1139
    private Set<String> serialNumberDetailsToSerialNumbers(Set<SerialNumberDetail> serialNumberDetails) {
1140
        Set<String> serialNumbers = new HashSet<>();
1141
        for (SerialNumberDetail serialNumberDetail : serialNumberDetails) {
1142
            if (serialNumberDetail.getSerialNumber() != null && !serialNumberDetail.getSerialNumber().isEmpty()) {
1143
                serialNumbers.add(serialNumberDetail.getSerialNumber());
1144
            }
1145
        }
1146
        return serialNumbers;
1147
    }
23650 amit.gupta 1148
 
32145 tejbeer 1149
    @Override
1150
    public InvoicePdfModel getInvoicePdfModel(int orderId) throws ProfitMandiBusinessException {
1151
        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(orderId);
1152
        return this.getInvoicePdfModel(fofoOrder);
1153
    }
23650 amit.gupta 1154
 
32145 tejbeer 1155
    @Override
1156
    @Cacheable(value = "order.dummymodel", cacheManager = "oneDayCacheManager")
1157
    public InvoicePdfModel getDummyPdfModel(String serialNumber) throws ProfitMandiBusinessException {
1158
        List<WarehouseInventoryItem> warehouseInventoryItems = warehouseInventoryItemRepository.selectWarehouseInventoryItemBySerailNumbers(Arrays.asList(serialNumber));
1159
        if (warehouseInventoryItems.size() > 0) {
1160
            WarehouseInventoryItem warehouseInventoryItem = warehouseInventoryItems.get(0);
1161
            int currentQuantity = warehouseInventoryItems.get(0).getCurrentQuantity();
1162
            if (currentQuantity > 0) {
1163
                throw new ProfitMandiBusinessException("Serial Number", serialNumber, "Serial Number exist in our warehouse");
1164
            } else {
1165
                try {
1166
                    InventoryItem inventoryItem = inventoryItemRepository.selectBySerialNumber(serialNumber);
1167
                    if (inventoryItem.getGoodQuantity() > 0) {
1168
                        throw new ProfitMandiBusinessException("Serial Number", serialNumber, "Serial Number is not yet billed by the partner");
1169
                    } else {
1170
                        List<ScanRecord> scanRecords = scanRecordRepository.selectByInventoryItemId(inventoryItem.getId());
1171
                        Optional<ScanRecord> scanRecord = scanRecords.stream().filter(x -> x.getOrderId() != 0).findFirst();
1172
                        if (scanRecord.isPresent()) {
1173
                            FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(scanRecord.get().getOrderId());
1174
                            orderIdsConsumed.add(fofoOrder.getId());
1175
                            return this.getInvoicePdfModel(fofoOrder);
1176
                        } else {
1177
                            throw new ProfitMandiBusinessException("Serial Number", serialNumber, "Serial Number returned by partner, but in transit");
1178
                        }
1179
                    }
1180
                } catch (Exception e) {
1181
                    int itemId = warehouseInventoryItem.getItemId();
1182
                    if (serialNumberOrderIdMap.containsKey(serialNumber)) {
1183
                        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(serialNumberOrderIdMap.get(serialNumber));
1184
                        InvoicePdfModel pdfModel = this.getInvoicePdfModel(fofoOrder.getId());
1185
                        this.modifyDummyModel(fofoOrder, pdfModel, itemId, serialNumber);
1186
                        return pdfModel;
1187
                    }
1188
                    // Map this serialNumber for dummy billing
1189
                    LocalDateTime grnDate = warehouseInventoryItem.getCreated();
1190
                    Random random = new Random();
1191
                    int randomDays = random.ints(2, 15).findFirst().getAsInt();
1192
                    LocalDateTime saleDate = grnDate.plusDays(randomDays);
1193
                    if (saleDate.isAfter(LocalDate.now().atStartOfDay())) {
1194
                        saleDate = LocalDateTime.now().minusDays(2);
1195
                    }
1196
                    Random offsetRandom = new Random();
1197
                    int offset = offsetRandom.ints(2, 100).findFirst().getAsInt();
1198
                    FofoOrder fofoOrder = fofoOrderRepository.selectFirstOrderAfterDate(saleDate, offset);
1199
                    while (orderIdsConsumed.contains(fofoOrder.getId())) {
1200
                        Random offsetRandom2 = new Random();
1201
                        int offset2 = offsetRandom2.ints(2, 100).findFirst().getAsInt();
1202
                        FofoOrder fofoOrder2 = fofoOrderRepository.selectFirstOrderAfterDate(saleDate, offset2);
1203
                        if (fofoOrder2 != null) {
1204
                            fofoOrder = fofoOrder2;
1205
                        }
1206
                    }
1207
                    InvoicePdfModel pdfModel = this.getInvoicePdfModel(fofoOrder.getId());
1208
                    orderIdsConsumed.add(fofoOrder.getId());
1209
                    this.modifyDummyModel(fofoOrder, pdfModel, itemId, serialNumber);
1210
                    return pdfModel;
27516 amit.gupta 1211
 
32145 tejbeer 1212
                }
1213
            }
1214
        } else {
1215
            throw new ProfitMandiBusinessException("Serial Number", serialNumber, "Serial Number does not exist in our warehouse");
1216
        }
1217
    }
27516 amit.gupta 1218
 
33665 ranu 1219
    void modifyDummyModel(FofoOrder fofoOrder, InvoicePdfModel pdfModel, int itemId, String serialNumber) throws
1220
            ProfitMandiBusinessException {
28166 tejbeer 1221
 
32145 tejbeer 1222
        int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoOrder.getFofoId());
27516 amit.gupta 1223
 
32145 tejbeer 1224
        Address retailerAddress = addressRepository.selectById(retailerAddressId);
1225
        Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
27516 amit.gupta 1226
 
32145 tejbeer 1227
        CustomerAddress customerAddress = customer.getCustomerAddress().stream().filter(x -> x.getId() == fofoOrder.getCustomerAddressId()).findFirst().get();
27516 amit.gupta 1228
 
32145 tejbeer 1229
        Integer stateId = null;
1230
        if (customerAddress.getState().equals(retailerAddress.getState())) {
1231
            try {
1232
                // stateId =
1233
                // Long.valueOf(Utils.getStateInfo(customerAddress.getState()).getId()).intValue();
30527 tejbeer 1234
 
32145 tejbeer 1235
                stateId = Long.valueOf(stateRepository.selectByName(customerAddress.getState()).getId()).intValue();
1236
            } catch (Exception e) {
1237
                LOGGER.error("Unable to get state rates");
1238
            }
1239
        }
1240
        CustomOrderItem cli = pdfModel.getOrderItems().stream().findFirst().get();
1241
        List<FofoOrderItem> fofoOrderItems = Arrays.asList(this.getDummyFofoOrderItem(itemId, fofoOrder.getId(), serialNumber, stateId));
1242
        pdfModel.setPaymentOptions(pdfModel.getPaymentOptions().stream().limit(1).collect(Collectors.toList()));
1243
        CustomPaymentOption paymentOption = pdfModel.getPaymentOptions().get(0);
1244
        paymentOption.setAmount(fofoOrderItems.get(0).getMop());
33298 amit.gupta 1245
        List<CustomOrderItem> customerFofoOrderItems = new ArrayList<>();
32145 tejbeer 1246
        for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
1247
            CustomOrderItem customFofoOrderItem = new CustomOrderItem();
1248
            float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
1249
            float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
1250
            float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
27516 amit.gupta 1251
 
32145 tejbeer 1252
            customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));
1253
            customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
1254
            Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());
1255
            // LOGGER.info("serialNumbers {}", serialNumbers);
1256
            // LOGGER.info("serialNumbers is empty {}", serialNumbers.isEmpty());
1257
            if (!serialNumbers.isEmpty()) {
1258
                customFofoOrderItem.setDescription(
1259
                        customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
1260
            }
1261
            customFofoOrderItem.setRate(taxableSellingPrice);
1262
            customFofoOrderItem.setDiscount(taxableDiscountPrice);
1263
            customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());
1264
            customFofoOrderItem.setNetAmount(
1265
                    (fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * fofoOrderItem.getQuantity());
1266
            float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
1267
            float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
1268
            float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
1269
            customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
1270
            customFofoOrderItem.setIgstAmount(igstAmount);
1271
            customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
1272
            customFofoOrderItem.setCgstAmount(cgstAmount);
1273
            customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
1274
            customFofoOrderItem.setSgstAmount(sgstAmount);
1275
            customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
1276
            customerFofoOrderItems.add(customFofoOrderItem);
1277
        }
1278
        pdfModel.setTotalAmount(paymentOption.getAmount());
1279
        pdfModel.setOrderItems(customerFofoOrderItems);
28166 tejbeer 1280
 
32145 tejbeer 1281
    }
27516 amit.gupta 1282
 
32145 tejbeer 1283
    private InvoicePdfModel getInvoicePdfModel(FofoOrder fofoOrder) throws ProfitMandiBusinessException {
23650 amit.gupta 1284
 
32145 tejbeer 1285
        List<PaymentOptionTransaction> paymentOptionTransactions = paymentOptionTransactionRepository.selectByReferenceIdAndTypes(fofoOrder.getId(), Arrays.asList(PaymentOptionReferenceType.ORDER, PaymentOptionReferenceType.INSURANCE));
23650 amit.gupta 1286
 
32145 tejbeer 1287
        List<CustomPaymentOption> paymentOptions = new ArrayList<>();
23552 amit.gupta 1288
 
32145 tejbeer 1289
        InvoicePdfModel pdfModel = new InvoicePdfModel();
33795 ranu 1290
 
1291
 
1292
        List<FofoOrderItem> fofoOrderItems = this.getByOrderId(fofoOrder.getId());
1293
 
1294
        double upgradePartnerDiscount = 0;
1295
 
1296
        for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
1297
 
1298
            Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());
1299
            for (String serialNumber : serialNumbers) {
1300
                UpgradeOffer upgradeOffer = upgradeOfferRepository.selectBySerialNumber(serialNumber);
1301
                if (upgradeOffer != null) {
1302
                    CustomerOfferItem customerOfferItem = customerOfferItemRepository.selectById(upgradeOffer.getCustomerOfferItemId());
1303
                    upgradePartnerDiscount += customerOfferItem.getDealerPayout();
1304
                } else {
1305
                    upgradePartnerDiscount += 0;
1306
                }
1307
            }
1308
 
1309
 
1310
        }
1311
 
1312
        boolean hasSamsungUpgrade = paymentOptionTransactions.stream()
1313
                .anyMatch(transaction ->
1314
                        "SAMSUNG UPGRADE".equals(paymentOptionRepository
1315
                                .selectById(transaction.getPaymentOptionId())
1316
                                .getName()));
1317
 
1318
        LOGGER.info("paymentOptionTransactions - {}", paymentOptionTransactions);
1319
        LOGGER.info("hasSamsungUpgrade - {}", hasSamsungUpgrade);
1320
 
1321
        double cashDiscount = paymentOptionTransactions.stream()
1322
                .filter(x -> "CASH DISCOUNT".equals(paymentOptionRepository.selectById(x.getPaymentOptionId()).getName())).mapToDouble(x -> x.getAmount()).findFirst().orElse(0);
1323
 
1324
        LOGGER.info("cashDiscount - {}", cashDiscount);
1325
 
32145 tejbeer 1326
        for (PaymentOptionTransaction paymentOptionTransaction : paymentOptionTransactions) {
33795 ranu 1327
            String paymentOptionName = paymentOptionRepository.selectById(paymentOptionTransaction.getPaymentOptionId()).getName();
1328
 
32145 tejbeer 1329
            CustomPaymentOption cpi = new CustomPaymentOption();
33795 ranu 1330
            LOGGER.info("paymentOptionName {}", paymentOptionName);
1331
 
1332
            float amountToSet = paymentOptionTransaction.getAmount();
1333
 
1334
            if ("SAMSUNG UPGRADE".equals(paymentOptionName) && hasSamsungUpgrade) {
1335
                if (cashDiscount > upgradePartnerDiscount) {
1336
                    amountToSet += (float) upgradePartnerDiscount;
1337
                } else {
1338
                    amountToSet += (float) cashDiscount;
1339
                }
1340
 
1341
            } else if ("CASH".equals(paymentOptionName) && !hasSamsungUpgrade) {
1342
                amountToSet += ((float) cashDiscount - (float) upgradePartnerDiscount);
1343
 
1344
            } else if ("CASH".equals(paymentOptionName) && hasSamsungUpgrade && (cashDiscount > upgradePartnerDiscount)) {
1345
                amountToSet += ((float) cashDiscount - (float) upgradePartnerDiscount);
1346
 
1347
            }
1348
 
1349
            cpi.setAmount(amountToSet);
1350
            cpi.setPaymentOption(paymentOptionName);
1351
 
32145 tejbeer 1352
            paymentOptions.add(cpi);
1353
        }
24215 amit.gupta 1354
 
33795 ranu 1355
 
32145 tejbeer 1356
        pdfModel.setTitle("Retailer Invoice");
1357
        Optional<FofoOrderItem> fofoOrderItemOptional = fofoOrderItems.stream().findAny();
1358
        if (fofoOrderItemOptional.isPresent() && fofoOrderItemOptional.get().equals("NOGST")) {
1359
            pdfModel.setTitle("Security Deposit Receipt");
1360
        }
1361
        pdfModel.setPaymentOptions(paymentOptions);
1362
        pdfModel.setAuther("SmartDukaan");
1363
        pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));
23650 amit.gupta 1364
 
32145 tejbeer 1365
        // insurance calculation
1366
        List<InsurancePolicy> insurancePolicies = insurancePolicyRepository.selectByRetailerIdInvoiceNumber(fofoOrder.getInvoiceNumber());
33298 amit.gupta 1367
        List<CustomInsurancePolicy> customInsurancePolicies = new ArrayList<>();
32145 tejbeer 1368
        final float totalInsuranceTaxRate = 18;
1369
        for (InsurancePolicy insurancePolicy : insurancePolicies) {
1370
            float taxableInsurancePrice = insurancePolicy.getSaleAmount() / (1 + totalInsuranceTaxRate / 100);
1371
            CustomInsurancePolicy customInsurancePolicy = new CustomInsurancePolicy();
1372
            customInsurancePolicy.setDescription(insurancePolicy.getPolicyPlan() + " for Device #" + insurancePolicy.getSerialNumber() + "\n Plan Reference - " + insurancePolicy.getPolicyNumber());
1373
            customInsurancePolicy.setHsnCode("998716");
1374
            customInsurancePolicy.setRate(taxableInsurancePrice);
1375
            customInsurancePolicy.setIgstRate(18);
1376
            customInsurancePolicy.setIgstAmount(taxableInsurancePrice * 18 / 100);
1377
            customInsurancePolicy.setCgstRate(9);
1378
            customInsurancePolicy.setCgstAmount(taxableInsurancePrice * 9 / 100);
1379
            customInsurancePolicy.setSgstRate(9);
1380
            customInsurancePolicy.setSgstAmount(taxableInsurancePrice * 9 / 100);
1381
            customInsurancePolicy.setNetAmount(insurancePolicy.getSaleAmount());
1382
            customInsurancePolicies.add(customInsurancePolicy);
1383
        }
1384
        pdfModel.setInsurancePolicies(customInsurancePolicies);
24275 amit.gupta 1385
 
32145 tejbeer 1386
        Retailer retailer = retailerRepository.selectById(fofoOrder.getFofoId());
1387
        PrivateDealUser privateDealUser = null;
1388
        try {
1389
            privateDealUser = privateDealUserRepository.selectById(retailer.getId());
1390
        } catch (ProfitMandiBusinessException profitMandiBusinessException) {
1391
            LOGGER.error("Private Deal User not found : ", profitMandiBusinessException);
1392
        }
23650 amit.gupta 1393
 
32145 tejbeer 1394
        User user = userRepository.selectById(userAccountRepository.selectUserIdByRetailerId(retailer.getId()));
1395
        CustomRetailer customRetailer = new CustomRetailer();
1396
        customRetailer.setBusinessName(retailer.getName());
1397
        customRetailer.setMobileNumber(user.getMobileNumber());
1398
        // customRetailer.setTinNumber(retailer.getNumber());
1399
        if (privateDealUser == null) {
1400
            customRetailer.setGstNumber(null);
1401
        } else {
1402
            if (null != privateDealUser.getCounterId()) {
1403
                Counter counter = counterRepository.selectById(privateDealUser.getCounterId());
1404
                customRetailer.setGstNumber(counter.getGstin());
1405
            } else {
1406
                customRetailer.setGstNumber(null);
1407
            }
1408
        }
1409
        Address retailerAddress = addressRepository.selectById(retailerRegisteredAddressRepository.selectAddressIdByRetailerId(retailer.getId()));
1410
        customRetailer.setAddress(this.createCustomAddress(retailerAddress));
1411
        pdfModel.setRetailer(customRetailer);
23650 amit.gupta 1412
 
33089 amit.gupta 1413
        pdfModel.setCustomer(getCustomCustomer(fofoOrder, customRetailer.getAddress()));
1414
        pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
1415
        pdfModel.setTotalAmount(fofoOrder.getTotalAmount());
1416
 
1417
 
33298 amit.gupta 1418
        List<CustomOrderItem> customerFofoOrderItems = new ArrayList<>();
32145 tejbeer 1419
        for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
1420
            float discount = fofoOrderItem.getDiscount();
1421
            CustomOrderItem customFofoOrderItem = new CustomOrderItem();
1422
            float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
1423
            float taxableSellingPrice = (fofoOrderItem.getSellingPrice() + discount) / (1 + totalTaxRate / 100);
1424
            float taxableDiscountPrice = discount / (1 + totalTaxRate / 100);
23650 amit.gupta 1425
 
32145 tejbeer 1426
            customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));
1427
            customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
1428
            Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());
32816 ranu 1429
            List<FofoNonSerializeSerial> nonSerializeSerials = fofoNonSerializeSerialRepository.selectByItemIdAndOrderId(fofoOrderItem.getId());
1430
            // Extract serial numbers from FofoNonSerializeSerial entities
1431
            List<String> customSerialNumbers = nonSerializeSerials.stream().map(FofoNonSerializeSerial::getSerialNumber).collect(Collectors.toList());
1432
            LOGGER.info("nonSerializeSerials {}", nonSerializeSerials);
32145 tejbeer 1433
            if (!serialNumbers.isEmpty()) {
1434
                customFofoOrderItem.setDescription(
1435
                        customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
1436
            }
32816 ranu 1437
            if (!customSerialNumbers.isEmpty()) {
1438
                customFofoOrderItem.setDescription(
1439
                        customFofoOrderItem.getDescription() + "\n SerialNumber - " + String.join(", ", customSerialNumbers));
1440
            }
32145 tejbeer 1441
            customFofoOrderItem.setRate(taxableSellingPrice);
1442
            customFofoOrderItem.setDiscount(taxableDiscountPrice);
1443
            customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());
1444
            customFofoOrderItem.setNetAmount(fofoOrderItem.getSellingPrice() * fofoOrderItem.getQuantity());
1445
            float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
1446
            float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
1447
            float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
1448
            customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
1449
            customFofoOrderItem.setIgstAmount(igstAmount);
1450
            customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
1451
            customFofoOrderItem.setCgstAmount(cgstAmount);
1452
            customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
1453
            customFofoOrderItem.setSgstAmount(sgstAmount);
1454
            customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
1455
            customerFofoOrderItems.add(customFofoOrderItem);
1456
        }
1457
        pdfModel.setOrderItems(customerFofoOrderItems);
32627 ranu 1458
        String customerAddressStateCode = "";
32145 tejbeer 1459
        String partnerAddressStateCode = stateRepository.selectByName(pdfModel.getRetailer().getAddress().getState()).getCode();
32627 ranu 1460
        if (pdfModel.getCustomer() != null && pdfModel.getCustomer().getAddress() != null &&
1461
                pdfModel.getCustomer().getAddress().getState() != null &&
1462
                !pdfModel.getCustomer().getAddress().getState().trim().isEmpty()) {
1463
            customerAddressStateCode = stateRepository.selectByName(pdfModel.getCustomer().getAddress().getState()).getCode();
1464
        }
1465
 
32145 tejbeer 1466
        pdfModel.setPartnerAddressStateCode(partnerAddressStateCode);
32627 ranu 1467
        if (!customerAddressStateCode.equals("")) {
1468
            pdfModel.setCustomerAddressStateCode(customerAddressStateCode);
1469
        }
32145 tejbeer 1470
        pdfModel.setCancelled(fofoOrder.getCancelledTimestamp() != null);
1471
        List<String> tncs = new ArrayList<>();
1472
        tncs.add("I agree that goods received are in good working condition");
1473
        tncs.add("Goods once sold cannot be exchanged or taken back");
1474
        tncs.add("Warranty for the goods received by me is the responsibility of the manufacturer only.");
1475
        tncs.add("Customer needs to activate the handset at the time of delivery to be eligible for the discount");
1476
        tncs.add(
1477
                "Customers requesting Tempered Glass Replacement will have to bring the broken tempered glass, either pasted on the phone or along with the phone");
1478
        tncs.add("Service fee of Rs.20 will be chargeable for each Tempered Glass Replacement");
1479
        if (pdfModel.getInsurancePolicies() != null && pdfModel.getInsurancePolicies().size() > 0) {
1480
            tncs.add("Damage protection provided is the responisibility of Protection Provider only");
1481
        }
1482
        pdfModel.setTncs(tncs);
1483
        return pdfModel;
23650 amit.gupta 1484
 
32145 tejbeer 1485
    }
23650 amit.gupta 1486
 
33665 ranu 1487
    private CustomCustomer getCustomCustomer(FofoOrder fofoOrder, CustomAddress retailerAddress) throws
1488
            ProfitMandiBusinessException {
32145 tejbeer 1489
        Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
1490
        CustomCustomer customCustomer = new CustomCustomer();
1491
        customCustomer.setFirstName(customer.getFirstName());
1492
        customCustomer.setLastName(customer.getLastName());
1493
        customCustomer.setEmailId(customer.getEmailId());
1494
        customCustomer.setMobileNumber(customer.getMobileNumber());
1495
        customCustomer.setGstNumber(fofoOrder.getCustomerGstNumber());
32627 ranu 1496
        if (fofoOrder.getCustomerAddressId() != 0) {
1497
            CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());
1498
            customCustomer.setAddress(this.createCustomAddress(customerAddress));
1499
        } else {
33089 amit.gupta 1500
 
1501
            customCustomer.setAddress(this.createCustomAddressWithoutId(customCustomer, retailerAddress));
32627 ranu 1502
        }
32145 tejbeer 1503
        return customCustomer;
32627 ranu 1504
 
32145 tejbeer 1505
    }
23655 amit.gupta 1506
 
32145 tejbeer 1507
    @Override
1508
    public InvoicePdfModel getInvoicePdfModel(int fofoId, int orderId) throws ProfitMandiBusinessException {
1509
        FofoOrder fofoOrder = fofoOrderRepository.selectByFofoIdAndOrderId(fofoId, orderId);
1510
        return this.getInvoicePdfModel(fofoOrder);
1511
    }
23650 amit.gupta 1512
 
32145 tejbeer 1513
    public String getBillingAddress(CustomerAddress customerAddress) {
1514
        StringBuilder address = new StringBuilder();
1515
        if ((customerAddress.getLine1() != null) && (!customerAddress.getLine1().isEmpty())) {
1516
            address.append(customerAddress.getLine1());
1517
            address.append(", ");
1518
        }
22859 ashik.ali 1519
 
32145 tejbeer 1520
        if ((customerAddress.getLine2() != null) && (!customerAddress.getLine2().isEmpty())) {
1521
            address.append(customerAddress.getLine2());
1522
            address.append(", ");
1523
        }
22859 ashik.ali 1524
 
32145 tejbeer 1525
        if ((customerAddress.getLandmark() != null) && (!customerAddress.getLandmark().isEmpty())) {
1526
            address.append(customerAddress.getLandmark());
1527
            address.append(", ");
1528
        }
22859 ashik.ali 1529
 
32145 tejbeer 1530
        if ((customerAddress.getCity() != null) && (!customerAddress.getCity().isEmpty())) {
1531
            address.append(customerAddress.getCity());
1532
            address.append(", ");
1533
        }
22859 ashik.ali 1534
 
32145 tejbeer 1535
        if ((customerAddress.getState() != null) && (!customerAddress.getState().isEmpty())) {
1536
            address.append(customerAddress.getState());
1537
        }
22859 ashik.ali 1538
 
32145 tejbeer 1539
        if ((customerAddress.getPinCode() != null) && (!customerAddress.getPinCode().isEmpty())) {
1540
            address.append("- ");
1541
            address.append(customerAddress.getPinCode());
1542
        }
22859 ashik.ali 1543
 
32145 tejbeer 1544
        return address.toString();
1545
    }
23650 amit.gupta 1546
 
32145 tejbeer 1547
    @Override
1548
    public List<CartFofo> cartCheckout(String cartJson) throws ProfitMandiBusinessException {
1549
        try {
1550
            JSONObject cartObject = new JSONObject(cartJson);
1551
            Iterator<?> keys = cartObject.keys();
23650 amit.gupta 1552
 
32145 tejbeer 1553
            Set<Integer> itemIds = new HashSet<>();
1554
            List<CartFofo> cartItems = new ArrayList<CartFofo>();
23650 amit.gupta 1555
 
32145 tejbeer 1556
            while (keys.hasNext()) {
1557
                String key = (String) keys.next();
1558
                if (cartObject.get(key) instanceof JSONObject) {
1559
                    LOGGER.info(cartObject.get(key).toString());
1560
                }
1561
                CartFofo cf = new CartFofo();
1562
                cf.setItemId(cartObject.getJSONObject(key).getInt("itemId"));
1563
                cf.setQuantity(cartObject.getJSONObject(key).getInt("quantity"));
1564
                if (cartObject.getJSONObject(key).has("poId")) {
23650 amit.gupta 1565
 
32145 tejbeer 1566
                    cf.setPoId(cartObject.getJSONObject(key).getInt("poId"));
1567
                    cf.setPoItemId(cartObject.getJSONObject(key).getInt("poItemId"));
1568
                }
1569
                if (cf.getQuantity() <= 0) {
1570
                    continue;
1571
                }
1572
                cartItems.add(cf);
1573
                itemIds.add(cartObject.getJSONObject(key).getInt("itemId"));
1574
            }
1575
            Map<Integer, Item> itemMap = new HashMap<Integer, Item>();
1576
            if (itemIds.size() > 0) {
1577
                List<Item> items = itemRepository.selectByIds(itemIds);
1578
                for (Item i : items) {
1579
                    itemMap.put(i.getId(), i);
1580
                }
23650 amit.gupta 1581
 
32145 tejbeer 1582
            }
1583
            for (CartFofo cf : cartItems) {
1584
                Item i = itemMap.get(cf.getItemId());
1585
                if (i == null) {
1586
                    continue;
1587
                }
1588
                cf.setDisplayName(getValidName(i.getBrand()) + " " + getValidName(i.getModelName()) + " " + getValidName(i.getModelNumber()) + " " + getValidName(i.getColor()).replaceAll("\\s+", " "));
1589
                cf.setItemType(i.getType());
1590
            }
1591
            return cartItems;
1592
        } catch (Exception e) {
1593
            LOGGER.error("Unable to Prepare cart to place order...", e);
1594
            throw new ProfitMandiBusinessException("cartData", cartJson, "FFORDR_1006");
1595
        }
1596
    }
23650 amit.gupta 1597
 
32145 tejbeer 1598
    @Override
33665 ranu 1599
    public Map<String, Object> getSaleHistory(int fofoId, SearchType searchType, String searchValue, LocalDateTime
1600
            startDate, LocalDateTime endDate, int offset, int limit) throws ProfitMandiBusinessException {
32145 tejbeer 1601
        long countItems = 0;
1602
        List<FofoOrder> fofoOrders = new ArrayList<>();
23650 amit.gupta 1603
 
32145 tejbeer 1604
        if (searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()) {
1605
            fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, null, null, offset, limit);
1606
            countItems = fofoOrderRepository.selectCountByCustomerMobileNumber(fofoId, searchValue, null, null);
1607
        } else if (searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()) {
1608
            fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, null, null, offset, limit);
1609
            countItems = fofoOrderRepository.selectCountByCustomerName(fofoId, searchValue, null, null);
1610
        } else if (searchType == SearchType.IMEI && !searchValue.isEmpty()) {
1611
            fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, null, null, offset, limit);
1612
            countItems = fofoOrderRepository.selectCountBySerialNumber(fofoId, searchValue, null, null);
1613
        } else if (searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()) {
1614
            fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, null, null, offset, limit);
1615
            countItems = fofoOrderRepository.selectCountByItemName(fofoId, searchValue, null, null);
1616
        } else if (searchType == SearchType.INVOICE_NUMBER && !searchValue.isEmpty()) {
1617
            fofoOrders = Arrays.asList(fofoOrderRepository.selectByFofoIdAndInvoiceNumber(fofoId, searchValue));
1618
            countItems = fofoOrders.size();
1619
        } else if (searchType == SearchType.DATE_RANGE) {
1620
            fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDate, endDate, offset, limit);
1621
            countItems = fofoOrderRepository.selectCountByFofoId(fofoId, startDate, endDate);
1622
        }
1623
        Map<String, Object> map = new HashMap<>();
23650 amit.gupta 1624
 
32145 tejbeer 1625
        map.put("saleHistories", fofoOrders);
1626
        map.put("start", offset + 1);
1627
        map.put("size", countItems);
1628
        map.put("searchType", searchType);
1629
        map.put("searchTypes", SearchType.values());
1630
        map.put("startDate", startDate);
1631
        map.put("searchValue", searchValue);
1632
        map.put(ProfitMandiConstants.END_TIME, endDate);
1633
        if (fofoOrders.size() < limit) {
1634
            map.put("end", offset + fofoOrders.size());
1635
        } else {
1636
            map.put("end", offset + limit);
1637
        }
1638
        return map;
1639
    }
30426 tejbeer 1640
 
33665 ranu 1641
    public ResponseEntity<?> downloadReportInCsv(org.apache.commons.io.output.ByteArrayOutputStream
1642
                                                         baos, List<List<?>> rows, String fileName) {
32145 tejbeer 1643
        final HttpHeaders headers = new HttpHeaders();
1644
        headers.set("Content-Type", "text/csv");
30426 tejbeer 1645
 
32145 tejbeer 1646
        headers.set("Content-disposition", "inline; filename=" + fileName + ".csv");
1647
        headers.setContentLength(baos.toByteArray().length);
23202 ashik.ali 1648
 
32145 tejbeer 1649
        final InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
1650
        final InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
30426 tejbeer 1651
 
33454 amit.gupta 1652
        return new ResponseEntity<>(inputStreamResource, headers, HttpStatus.OK);
32145 tejbeer 1653
    }
30157 manish 1654
 
32145 tejbeer 1655
    @Override
33665 ranu 1656
    public Map<String, Object> getSaleHistoryPaginated(int fofoId, SearchType searchType, String
1657
            searchValue, LocalDateTime startDate, LocalDateTime endDate, int offset, int limit) throws
1658
            ProfitMandiBusinessException {
32145 tejbeer 1659
        List<FofoOrder> fofoOrders = new ArrayList<>();
23650 amit.gupta 1660
 
32145 tejbeer 1661
        if (searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()) {
1662
            fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, startDate, endDate, offset, limit);
1663
        } else if (searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()) {
1664
            fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, startDate, endDate, offset, limit);
1665
        } else if (searchType == SearchType.IMEI && !searchValue.isEmpty()) {
1666
            fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, startDate, endDate, offset, limit);
1667
        } else if (searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()) {
1668
            fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, startDate, endDate, offset, limit);
24275 amit.gupta 1669
 
32145 tejbeer 1670
        } else if (searchType == SearchType.DATE_RANGE) {
1671
            fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDate, endDate, offset, limit);
1672
        }
1673
        Map<String, Object> map = new HashMap<>();
1674
        map.put("saleHistories", fofoOrders);
1675
        map.put("searchType", searchType);
1676
        map.put("searchTypes", SearchType.values());
1677
        map.put("startDate", startDate);
1678
        map.put("searchValue", searchValue);
1679
        map.put(ProfitMandiConstants.END_TIME, endDate);
1680
        return map;
1681
    }
23650 amit.gupta 1682
 
32145 tejbeer 1683
    private String getFofoStoreCode(int fofoId) throws ProfitMandiBusinessException {
1684
        FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
1685
        return fofoStore.getCode();
1686
    }
23650 amit.gupta 1687
 
32145 tejbeer 1688
    private String getValidName(String name) {
1689
        return name != null ? name : "";
1690
    }
23650 amit.gupta 1691
 
32145 tejbeer 1692
    private Set<String> toSerialNumbers(Set<FofoLineItem> fofoLineItems) {
1693
        Set<String> serialNumbers = new HashSet<>();
1694
        for (FofoLineItem fofoLineItem : fofoLineItems) {
1695
            if (fofoLineItem.getSerialNumber() != null && !fofoLineItem.getSerialNumber().isEmpty()) {
1696
                serialNumbers.add(fofoLineItem.getSerialNumber());
1697
            }
1698
        }
1699
        return serialNumbers;
1700
    }
23650 amit.gupta 1701
 
33520 amit.gupta 1702
    static final List<String> MOP_VOILATED_BRANDS = Arrays.asList("Live Demo", "Almost New");
1703
 
33665 ranu 1704
    private void validateDpPrice(int fofoId, Map<
1705
            Integer, PriceModel> itemIdMopPriceMap, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws
1706
            ProfitMandiBusinessException {
32420 amit.gupta 1707
        if (pricingService.getMopVoilatedRetailerIds().contains(fofoId)) return;
32145 tejbeer 1708
        for (Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoLineItemMap.entrySet()) {
1709
            int itemId = entry.getKey();
1710
            CustomFofoOrderItem customFofoOrderItem = entry.getValue();
1711
            LOGGER.info("CustomFofoOrderItem -- {}", customFofoOrderItem);
1712
            PriceModel priceModel = itemIdMopPriceMap.get(itemId);
1713
            Item item = itemRepository.selectById(itemId);
33520 amit.gupta 1714
            if (!MOP_VOILATED_BRANDS.contains(item.getBrand()) && (item.getCategoryId() == ProfitMandiConstants.MOBILE_CATEGORY_ID || item.getCategoryId() == ProfitMandiConstants.TABLET_CATEGORY_ID || item.getCategoryId() == ProfitMandiConstants.LED_CATEGORY_ID) && customFofoOrderItem.getSerialNumberDetails().stream().filter(x -> org.apache.commons.lang.StringUtils.isNotEmpty(x.getSerialNumber())).collect(Collectors.toList()).size() > 0) {
32145 tejbeer 1715
                if (Utils.compareFloat(priceModel.getPrice(), customFofoOrderItem.getSellingPrice() + customFofoOrderItem.getDiscountAmount()) > 0) {
1716
                    throw new ProfitMandiBusinessException("Selling Price for ", item.getItemDescription(), "FFORDR_1010");
1717
                }
1718
            } else {
33520 amit.gupta 1719
                if (!MOP_VOILATED_BRANDS.contains(item.getBrand()) && priceModel.getPurchasePrice() > customFofoOrderItem.getSellingPrice()) {
32145 tejbeer 1720
                    throw new ProfitMandiBusinessException("Selling Price", itemRepository.selectById(itemId).getItemDescription(), "Selling Price should not be less than DP");
1721
                }
1722
            }
1723
        }
1724
    }
24275 amit.gupta 1725
 
33665 ranu 1726
    private void validateMopPrice(int fofoId, Map<
1727
            Integer, PriceModel> itemIdMopPriceMap, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws
1728
            ProfitMandiBusinessException {
32420 amit.gupta 1729
        if (pricingService.getMopVoilatedRetailerIds().contains(fofoId)) return;
32145 tejbeer 1730
        Map<Integer, Float> invalidMopItemIdPriceMap = new HashMap<>();
1731
        for (Map.Entry<Integer, PriceModel> entry : itemIdMopPriceMap.entrySet()) {
1732
            CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoLineItemMap.get(entry.getKey());
1733
            Item item = itemRepository.selectById(customFofoOrderItem.getItemId());
33520 amit.gupta 1734
            if (!(MOP_VOILATED_BRANDS.contains(item.getBrand()) || item.getCategoryId() != ProfitMandiConstants.MOBILE_CATEGORY_ID || item.getCategoryId() != ProfitMandiConstants.TABLET_CATEGORY_ID) && customFofoOrderItem.getSellingPrice() + customFofoOrderItem.getDiscountAmount() < entry.getValue().getPrice()) {
32145 tejbeer 1735
                invalidMopItemIdPriceMap.put(entry.getKey(), customFofoOrderItem.getSellingPrice());
1736
            }
1737
        }
23650 amit.gupta 1738
 
32145 tejbeer 1739
        if (!invalidMopItemIdPriceMap.isEmpty()) {
1740
            LOGGER.error("Invalid itemIds selling prices{} should be greater than mop prices {}", invalidMopItemIdPriceMap, itemIdMopPriceMap);
1741
            throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidMopItemIdPriceMap, "FFORDR_1010");
1742
        }
23650 amit.gupta 1743
 
32145 tejbeer 1744
    }
23650 amit.gupta 1745
 
33665 ranu 1746
    private void updateInventoryItemsAndScanRecord(Set<InventoryItem> inventoryItems, int fofoId, Map<
1747
            Integer, Integer> inventoryItemQuantityUsed, int fofoOrderId) {
32145 tejbeer 1748
        for (InventoryItem inventoryItem : inventoryItems) {
1749
            inventoryItem.setLastScanType(ScanType.SALE);
33087 amit.gupta 1750
            inventoryItem.setUpdateTimestamp(LocalDateTime.now());
32145 tejbeer 1751
            ScanRecord scanRecord = new ScanRecord();
1752
            scanRecord.setInventoryItemId(inventoryItem.getId());
1753
            scanRecord.setFofoId(fofoId);
1754
            scanRecord.setOrderId(fofoOrderId);
1755
            // correct this
1756
            scanRecord.setQuantity(inventoryItemQuantityUsed.get(inventoryItem.getId()));
1757
            scanRecord.setType(ScanType.SALE);
1758
            scanRecordRepository.persist(scanRecord);
1759
            purchaseReturnItemRepository.deleteById(inventoryItem.getId());
23650 amit.gupta 1760
 
32145 tejbeer 1761
        }
1762
    }
23650 amit.gupta 1763
 
33665 ranu 1764
    private void createFofoLineItem(int fofoOrderItemId, Set<
1765
            InventoryItem> inventoryItems, Map<Integer, Integer> inventoryItemIdQuantityUsed) {
32145 tejbeer 1766
        for (InventoryItem inventoryItem : inventoryItems) {
1767
            FofoLineItem fofoLineItem = new FofoLineItem();
1768
            fofoLineItem.setFofoOrderItemId(fofoOrderItemId);
1769
            fofoLineItem.setSerialNumber(inventoryItem.getSerialNumber());
1770
            fofoLineItem.setInventoryItemId(inventoryItem.getId());
1771
            fofoLineItem.setQuantity(inventoryItemIdQuantityUsed.get(inventoryItem.getId()));
1772
            fofoLineItemRepository.persist(fofoLineItem);
1773
        }
1774
    }
23650 amit.gupta 1775
 
33665 ranu 1776
    private FofoOrderItem createAndGetFofoOrderItem(CustomFofoOrderItem customFofoOrderItem, int fofoOrderId, Map<
1777
            Integer, Item> itemMap, Set<InventoryItem> inventoryItems, Integer stateId) throws
1778
            ProfitMandiBusinessException {
32145 tejbeer 1779
        FofoOrderItem fofoOrderItem = new FofoOrderItem();
1780
        fofoOrderItem.setItemId(customFofoOrderItem.getItemId());
1781
        fofoOrderItem.setQuantity(customFofoOrderItem.getQuantity());
1782
        fofoOrderItem.setSellingPrice(customFofoOrderItem.getSellingPrice());
1783
        fofoOrderItem.setOrderId(fofoOrderId);
1784
        TagListing tl = tagListingRepository.selectByItemId(customFofoOrderItem.getItemId());
1785
        // In case listing gets removed rebill it using the selling price
1786
        if (tl != null) {
1787
            fofoOrderItem.setDp(tl.getSellingPrice());
1788
            fofoOrderItem.setMop(tl.getMop());
1789
        } else {
1790
            fofoOrderItem.setDp(customFofoOrderItem.getSellingPrice());
1791
            fofoOrderItem.setMop(customFofoOrderItem.getSellingPrice());
1792
        }
1793
        fofoOrderItem.setDiscount(customFofoOrderItem.getDiscountAmount());
24823 amit.gupta 1794
 
32145 tejbeer 1795
        Item item = itemMap.get(customFofoOrderItem.getItemId());
1796
        Map<Integer, GstRate> itemIdStateTaxRateMap = null;
1797
        if (stateId != null) {
1798
            itemIdStateTaxRateMap = stateGstRateRepository.getStateTaxRate(new ArrayList<>(itemMap.keySet()), stateId);
1799
        } else {
1800
            itemIdStateTaxRateMap = stateGstRateRepository.getIgstTaxRate(new ArrayList<>(itemMap.keySet()));
1801
        }
1802
        for (InventoryItem inventoryItem : inventoryItems) {
23650 amit.gupta 1803
 
32145 tejbeer 1804
            fofoOrderItem.setIgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getIgstRate());
23650 amit.gupta 1805
 
32145 tejbeer 1806
            fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getCgstRate());
1807
            fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getSgstRate());
27516 amit.gupta 1808
 
1809
 
32145 tejbeer 1810
            fofoOrderItem.setHsnCode(inventoryItem.getHsnCode());
1811
            break;
1812
        }
1813
        fofoOrderItem.setBrand(item.getBrand());
1814
        fofoOrderItem.setModelName(item.getModelName());
1815
        fofoOrderItem.setModelNumber(item.getModelNumber());
1816
        fofoOrderItem.setColor(item.getColor());
1817
        fofoOrderItemRepository.persist(fofoOrderItem);
1818
        return fofoOrderItem;
1819
    }
27516 amit.gupta 1820
 
33665 ranu 1821
    private FofoOrderItem getDummyFofoOrderItem(int itemId, int fofoOrderId, String serialNumber, Integer stateId) throws
1822
            ProfitMandiBusinessException {
32145 tejbeer 1823
        Item item = itemRepository.selectById(itemId);
1824
        TagListing tl = tagListingRepository.selectByItemId(itemId);
1825
        FofoOrderItem fofoOrderItem = new FofoOrderItem();
1826
        fofoOrderItem.setItemId(itemId);
1827
        fofoOrderItem.setQuantity(1);
1828
        fofoOrderItem.setSellingPrice(tl.getMop());
1829
        fofoOrderItem.setOrderId(fofoOrderId);
1830
        // In case listing gets removed rebill it using the selling price
1831
        fofoOrderItem.setDp(tl.getSellingPrice());
1832
        fofoOrderItem.setMop(tl.getMop());
1833
        fofoOrderItem.setDiscount(0);
27516 amit.gupta 1834
 
32145 tejbeer 1835
        Map<Integer, GstRate> itemIdStateTaxRateMap = null;
1836
        if (stateId != null) {
1837
            itemIdStateTaxRateMap = stateGstRateRepository.getStateTaxRate(Arrays.asList(itemId), stateId);
1838
        } else {
1839
            itemIdStateTaxRateMap = stateGstRateRepository.getIgstTaxRate(Arrays.asList(itemId));
1840
        }
27516 amit.gupta 1841
 
32145 tejbeer 1842
        fofoOrderItem.setIgstRate(itemIdStateTaxRateMap.get(itemId).getIgstRate());
27516 amit.gupta 1843
 
32145 tejbeer 1844
        fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(itemId).getCgstRate());
1845
        fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(itemId).getSgstRate());
23650 amit.gupta 1846
 
1847
 
32145 tejbeer 1848
        fofoOrderItem.setHsnCode(item.getHsnCode());
1849
        fofoOrderItem.setBrand(item.getBrand());
1850
        fofoOrderItem.setModelName(item.getModelName());
1851
        fofoOrderItem.setModelNumber(item.getModelNumber());
1852
        fofoOrderItem.setColor(item.getColor());
23650 amit.gupta 1853
 
32145 tejbeer 1854
        Set<FofoLineItem> fofoLineItems = new HashSet<>();
1855
        FofoLineItem fli = new FofoLineItem();
1856
        fli.setQuantity(1);
1857
        fli.setSerialNumber(serialNumber);
1858
        fofoLineItems.add(fli);
1859
        fofoOrderItem.setFofoLineItems(fofoLineItems);
22859 ashik.ali 1860
 
32145 tejbeer 1861
        return fofoOrderItem;
1862
    }
22859 ashik.ali 1863
 
33665 ranu 1864
    private void updateCurrentInventorySnapshot(List<CurrentInventorySnapshot> currentInventorySnapshots,
1865
                                                int fofoId, int itemId, int quantity) throws ProfitMandiBusinessException {
32145 tejbeer 1866
        for (CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {
1867
            if (currentInventorySnapshot.getItemId() == itemId && currentInventorySnapshot.getFofoId() == fofoId) {
1868
                currentInventorySnapshotRepository.updateAvailabilityByItemIdAndFofoId(itemId, fofoId, currentInventorySnapshot.getAvailability() - quantity);
1869
            }
1870
        }
1871
    }
23650 amit.gupta 1872
 
33665 ranu 1873
    private void createPaymentOptions(FofoOrder fofoOrder, Set<CustomPaymentOption> customPaymentOptions) throws
1874
            ProfitMandiBusinessException {
32145 tejbeer 1875
        for (CustomPaymentOption customPaymentOption : customPaymentOptions) {
1876
            if (customPaymentOption.getAmount() > 0) {
1877
                PaymentOptionTransaction paymentOptionTransaction = new PaymentOptionTransaction();
32627 ranu 1878
                LOGGER.error("error", fofoOrder.getId());
32145 tejbeer 1879
                paymentOptionTransaction.setReferenceId(fofoOrder.getId());
1880
                paymentOptionTransaction.setPaymentOptionId(customPaymentOption.getPaymentOptionId());
1881
                paymentOptionTransaction.setReferenceType(PaymentOptionReferenceType.ORDER);
1882
                paymentOptionTransaction.setAmount(customPaymentOption.getAmount());
1883
                paymentOptionTransaction.setFofoId(fofoOrder.getFofoId());
1884
                paymentOptionTransactionRepository.persist(paymentOptionTransaction);
1885
            }
1886
        }
1887
    }
22859 ashik.ali 1888
 
33665 ranu 1889
    private FofoOrder createAndGetFofoOrder(int customerId, String customerGstNumber, int fofoId, String
34319 amit.gupta 1890
            documentNumber, float totalAmount, int customerAddressId) {
32145 tejbeer 1891
        FofoOrder fofoOrder = new FofoOrder();
1892
        fofoOrder.setCustomerGstNumber(customerGstNumber);
1893
        fofoOrder.setCustomerId(customerId);
1894
        fofoOrder.setFofoId(fofoId);
1895
        fofoOrder.setInvoiceNumber(documentNumber);
1896
        fofoOrder.setTotalAmount(totalAmount);
1897
        fofoOrder.setCustomerAddressId(customerAddressId);
1898
        fofoOrderRepository.persist(fofoOrder);
1899
        return fofoOrder;
1900
    }
23650 amit.gupta 1901
 
33665 ranu 1902
    private void validateItemsSerializedNonSerialized
1903
            (List<Item> items, Map<Integer, CustomFofoOrderItem> customFofoOrderItemMap) throws
1904
            ProfitMandiBusinessException {
32145 tejbeer 1905
        List<Integer> invalidItemIdSerialNumbers = new ArrayList<Integer>();
1906
        List<Integer> itemIdNonSerializedSerialNumbers = new ArrayList<Integer>();
1907
        for (Item i : items) {
1908
            CustomFofoOrderItem customFofoOrderItem = customFofoOrderItemMap.get(i.getId());
1909
            if (i.getType().equals(ItemType.SERIALIZED)) {
1910
                if (customFofoOrderItem == null || customFofoOrderItem.getSerialNumberDetails().isEmpty()) {
1911
                    invalidItemIdSerialNumbers.add(i.getId());
1912
                }
1913
            } else {
1914
                Set<String> serialNumbers = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());
1915
                if (customFofoOrderItem == null || !serialNumbers.isEmpty()) {
1916
                    itemIdNonSerializedSerialNumbers.add(i.getId());
1917
                }
1918
            }
1919
        }
23650 amit.gupta 1920
 
32145 tejbeer 1921
        if (!invalidItemIdSerialNumbers.isEmpty()) {
1922
            LOGGER.error("Invalid itemId's serialNumbers for serialized{}", invalidItemIdSerialNumbers);
1923
            // itemId's are serialized you are saying these are not serialized
1924
            throw new ProfitMandiBusinessException("invalidItemIdSerialNumbers", invalidItemIdSerialNumbers, "FFORDR_1013");
1925
        }
22859 ashik.ali 1926
 
32145 tejbeer 1927
        if (!itemIdNonSerializedSerialNumbers.isEmpty()) {
1928
            LOGGER.error("Invalid itemId's serialNumbers for non serialized{}", itemIdNonSerializedSerialNumbers);
1929
            // itemId's are non serialized you are saying these are serialized
1930
            throw new ProfitMandiBusinessException("itemIdNonSerializedSerialNumbers", itemIdNonSerializedSerialNumbers, "FFORDR_1014");
1931
        }
1932
    }
22859 ashik.ali 1933
 
33665 ranu 1934
    private void validateCurrentInventorySnapshotQuantities
1935
            (List<CurrentInventorySnapshot> currentInventorySnapshots, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap) throws
1936
            ProfitMandiBusinessException {
32145 tejbeer 1937
        if (itemIdCustomFofoOrderItemMap.keySet().size() != currentInventorySnapshots.size()) {
1938
            throw new ProfitMandiBusinessException("quantiiesSize", currentInventorySnapshots.size(), "");
1939
        }
1940
        List<ItemIdQuantityAvailability> itemIdQuantityAvailabilities = new ArrayList<>(); // this is for error
1941
        LOGGER.info("currentInventorySnapshots " + currentInventorySnapshots);
1942
        LOGGER.info("CustomFofoLineItemMap {}", itemIdCustomFofoOrderItemMap);
1943
        for (CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {
1944
            CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoOrderItemMap.get(currentInventorySnapshot.getItemId());
1945
            LOGGER.info("customFofoOrderItem {}", customFofoOrderItem);
1946
            if (customFofoOrderItem.getQuantity() > currentInventorySnapshot.getAvailability()) {
1947
                ItemIdQuantityAvailability itemIdQuantityAvailability = new ItemIdQuantityAvailability();
1948
                itemIdQuantityAvailability.setItemId(customFofoOrderItem.getItemId());
1949
                Quantity quantity = new Quantity();
1950
                quantity.setAvailable(currentInventorySnapshot.getAvailability());
1951
                quantity.setRequested(customFofoOrderItem.getQuantity());
1952
                itemIdQuantityAvailability.setQuantity(quantity);
1953
                itemIdQuantityAvailabilities.add(itemIdQuantityAvailability);
1954
            }
1955
        }
22859 ashik.ali 1956
 
32145 tejbeer 1957
        if (!itemIdQuantityAvailabilities.isEmpty()) {
1958
            // itemIdQuantity request is not valid
1959
            LOGGER.error("Requested quantities should not be greater than currently available quantities {}", itemIdQuantityAvailabilities);
1960
            throw new ProfitMandiBusinessException("itemIdQuantityAvailabilities", itemIdQuantityAvailabilities, "FFORDR_1015");
1961
        }
1962
    }
22859 ashik.ali 1963
 
33665 ranu 1964
    private int getItemIdFromSerialNumber(Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap, String
1965
            serialNumber) {
32145 tejbeer 1966
        int itemId = 0;
1967
        for (Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoOrderItemMap.entrySet()) {
1968
            Set<SerialNumberDetail> serialNumberDetails = entry.getValue().getSerialNumberDetails();
1969
            for (SerialNumberDetail serialNumberDetail : serialNumberDetails) {
1970
                if (serialNumberDetail.getSerialNumber().equals(serialNumber)) {
1971
                    itemId = entry.getKey();
1972
                    break;
1973
                }
1974
            }
1975
        }
1976
        return itemId;
1977
    }
23650 amit.gupta 1978
 
32145 tejbeer 1979
    private Map<Integer, Item> toItemMap(List<Item> items) {
1980
        Function<Item, Integer> itemIdFunction = new Function<Item, Integer>() {
1981
            @Override
1982
            public Integer apply(Item item) {
1983
                return item.getId();
1984
            }
1985
        };
1986
        Function<Item, Item> itemFunction = new Function<Item, Item>() {
1987
            @Override
1988
            public Item apply(Item item) {
1989
                return item;
1990
            }
1991
        };
1992
        return items.stream().collect(Collectors.toMap(itemIdFunction, itemFunction));
1993
    }
23650 amit.gupta 1994
 
32145 tejbeer 1995
    private void setCustomerAddress(CustomerAddress customerAddress, CustomAddress customAddress) {
1996
        customerAddress.setName(customAddress.getName());
1997
        customerAddress.setLastName(customAddress.getLastName());
1998
        customerAddress.setLine1(customAddress.getLine1());
1999
        customerAddress.setLine2(customAddress.getLine2());
2000
        customerAddress.setLandmark(customAddress.getLandmark());
2001
        customerAddress.setCity(customAddress.getCity());
2002
        customerAddress.setPinCode(customAddress.getPinCode());
2003
        customerAddress.setState(customAddress.getState());
2004
        customerAddress.setCountry(customAddress.getCountry());
2005
        customerAddress.setPhoneNumber(customAddress.getPhoneNumber());
2006
    }
23650 amit.gupta 2007
 
32145 tejbeer 2008
    private CustomAddress createCustomAddress(Address address) {
2009
        CustomAddress customAddress = new CustomAddress();
2010
        customAddress.setName(address.getName());
2011
        customAddress.setLine1(address.getLine1());
2012
        customAddress.setLine2(address.getLine2());
2013
        customAddress.setLandmark(address.getLandmark());
2014
        customAddress.setCity(address.getCity());
2015
        customAddress.setPinCode(address.getPinCode());
2016
        customAddress.setState(address.getState());
2017
        customAddress.setCountry(address.getCountry());
2018
        customAddress.setPhoneNumber(address.getPhoneNumber());
2019
        return customAddress;
2020
    }
23650 amit.gupta 2021
 
32145 tejbeer 2022
    private CustomAddress createCustomAddress(CustomerAddress customerAddress) {
2023
        CustomAddress customAddress = new CustomAddress();
2024
        customAddress.setName(customerAddress.getName());
2025
        customAddress.setLastName(customerAddress.getLastName());
2026
        customAddress.setLine1(customerAddress.getLine1());
2027
        customAddress.setLine2(customerAddress.getLine2());
2028
        customAddress.setLandmark(customerAddress.getLandmark());
2029
        customAddress.setCity(customerAddress.getCity());
2030
        customAddress.setPinCode(customerAddress.getPinCode());
2031
        customAddress.setState(customerAddress.getState());
2032
        customAddress.setCountry(customerAddress.getCountry());
2033
        customAddress.setPhoneNumber(customerAddress.getPhoneNumber());
2034
        return customAddress;
2035
    }
23650 amit.gupta 2036
 
33665 ranu 2037
    private CustomAddress createCustomAddressWithoutId(CustomCustomer customerAddress, CustomAddress
2038
            retailerAddress) {
32627 ranu 2039
        CustomAddress customAddress = new CustomAddress();
2040
        customAddress.setName(customerAddress.getFirstName());
2041
        customAddress.setLastName(customerAddress.getLastName());
2042
        customAddress.setLine1("");
2043
        customAddress.setLine2("");
2044
        customAddress.setLandmark("");
33089 amit.gupta 2045
        customAddress.setCity(retailerAddress.getCity());
2046
        customAddress.setPinCode(retailerAddress.getPinCode());
2047
        customAddress.setState(retailerAddress.getState());
32627 ranu 2048
        customAddress.setCountry("");
2049
        customAddress.setPhoneNumber(customerAddress.getMobileNumber());
2050
        return customAddress;
2051
    }
2052
 
33665 ranu 2053
    private void validatePaymentOptionsAndTotalAmount(Set<CustomPaymentOption> customPaymentOptions,
2054
                                                      float totalAmount) throws ProfitMandiBusinessException {
32145 tejbeer 2055
        Set<Integer> paymentOptionIds = new HashSet<>();
23650 amit.gupta 2056
 
32145 tejbeer 2057
        float calculatedAmount = 0;
2058
        for (CustomPaymentOption customPaymentOption : customPaymentOptions) {
2059
            paymentOptionIds.add(customPaymentOption.getPaymentOptionId());
2060
            calculatedAmount = calculatedAmount + customPaymentOption.getAmount();
2061
        }
2062
        if (calculatedAmount != totalAmount) {
2063
            LOGGER.warn("Error occured while validating payment options amount - {} != TotalAmount {}", calculatedAmount, totalAmount);
2064
            throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_CALCULATED_AMOUNT, calculatedAmount, "FFORDR_1016");
2065
        }
23418 ashik.ali 2066
 
32145 tejbeer 2067
        List<Integer> foundPaymentOptionIds = paymentOptionRepository.selectIdsByIds(paymentOptionIds);
2068
        if (foundPaymentOptionIds.size() != paymentOptionIds.size()) {
2069
            paymentOptionIds.removeAll(foundPaymentOptionIds);
2070
            throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_ID, paymentOptionIds, "FFORDR_1017");
2071
        }
2072
    }
25101 amit.gupta 2073
 
32145 tejbeer 2074
    @Override
2075
    public List<FofoOrderItem> getByOrderId(int orderId) throws ProfitMandiBusinessException {
2076
        List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(orderId);
2077
        if (!fofoOrderItems.isEmpty()) {
2078
            List<FofoOrderItem> newFofoOrderItems = new ArrayList<>();
2079
            Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = this.toFofoOrderItemIdFofoLineItems(fofoOrderItems);
2080
            Iterator<FofoOrderItem> fofoOrderItemsIterator = fofoOrderItems.iterator();
2081
            while (fofoOrderItemsIterator.hasNext()) {
2082
                FofoOrderItem fofoOrderItem = fofoOrderItemsIterator.next();
2083
                fofoOrderItem.setFofoLineItems(fofoOrderItemIdFofoLineItemsMap.get(fofoOrderItem.getId()));
2084
                newFofoOrderItems.add(fofoOrderItem);
2085
                fofoOrderItemsIterator.remove();
2086
            }
2087
            fofoOrderItems = newFofoOrderItems;
2088
        }
2089
        return fofoOrderItems;
2090
    }
25101 amit.gupta 2091
 
32145 tejbeer 2092
    private Set<Integer> toFofoOrderItemIds(List<FofoOrderItem> fofoOrderItems) {
2093
        Function<FofoOrderItem, Integer> fofoOrderItemToFofoOrderItemIdFunction = new Function<FofoOrderItem, Integer>() {
2094
            @Override
2095
            public Integer apply(FofoOrderItem fofoOrderItem) {
2096
                return fofoOrderItem.getId();
2097
            }
2098
        };
2099
        return fofoOrderItems.stream().map(fofoOrderItemToFofoOrderItemIdFunction).collect(Collectors.toSet());
2100
    }
25101 amit.gupta 2101
 
33665 ranu 2102
    private Map<Integer, Set<FofoLineItem>> toFofoOrderItemIdFofoLineItems(List<FofoOrderItem> fofoOrderItems) throws
2103
            ProfitMandiBusinessException {
32145 tejbeer 2104
        Set<Integer> fofoOrderItemIds = this.toFofoOrderItemIds(fofoOrderItems);
2105
        List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIds);
2106
        Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = new HashMap<>();
2107
        for (FofoLineItem fofoLineItem : fofoLineItems) {
2108
            if (!fofoOrderItemIdFofoLineItemsMap.containsKey(fofoLineItem.getFofoOrderItemId())) {
2109
                Set<FofoLineItem> fofoLineItems2 = new HashSet<>();
2110
                fofoLineItems2.add(fofoLineItem);
2111
                fofoOrderItemIdFofoLineItemsMap.put(fofoLineItem.getFofoOrderItemId(), fofoLineItems2);
2112
            } else {
2113
                fofoOrderItemIdFofoLineItemsMap.get(fofoLineItem.getFofoOrderItemId()).add(fofoLineItem);
2114
            }
2115
        }
2116
        return fofoOrderItemIdFofoLineItemsMap;
2117
    }
25101 amit.gupta 2118
 
32145 tejbeer 2119
    @Override
33665 ranu 2120
    public void updateCustomerDetails(CustomCustomer customCustomer, String invoiceNumber) throws
2121
            ProfitMandiBusinessException {
32145 tejbeer 2122
        FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
2123
        Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
2124
        customer.setFirstName(customCustomer.getFirstName());
2125
        customer.setLastName(customCustomer.getLastName());
2126
        customer.setMobileNumber(customCustomer.getMobileNumber());
2127
        customer.setEmailId(customCustomer.getEmailId());
2128
        customerRepository.persist(customer);
34338 ranu 2129
        if (fofoOrder.getCustomerAddressId() == 0) {
2130
            CustomAddress customAddress = customCustomer.getAddress();
2131
 
2132
            if (customAddress == null ||
2133
                    isNullOrEmpty(customAddress.getName()) ||
2134
                    isNullOrEmpty(customAddress.getLastName()) ||
2135
                    isNullOrEmpty(customAddress.getLine1()) ||
2136
                    isNullOrEmpty(customAddress.getCity()) ||
2137
                    isNullOrEmpty(customAddress.getPinCode()) ||
2138
                    isNullOrEmpty(customAddress.getState()) ||
2139
                    isNullOrEmpty(customAddress.getCountry()) ||
2140
                    isNullOrEmpty(customAddress.getPhoneNumber())) {
2141
                throw new IllegalArgumentException("Required customer address fields are missing.");
2142
            }
2143
 
2144
            CustomerAddress customerAddress = new CustomerAddress();
2145
            customerAddress.setCustomerId(fofoOrder.getCustomerId());
2146
            customerAddress.setName(customAddress.getName());
2147
            customerAddress.setLastName(customAddress.getLastName());
2148
            customerAddress.setLine1(customAddress.getLine1());
2149
            customerAddress.setLine2(customAddress.getLine2());
2150
            customerAddress.setLandmark(customAddress.getLandmark());
2151
            customerAddress.setCity(customAddress.getCity());
2152
            customerAddress.setPinCode(customAddress.getPinCode());
2153
            customerAddress.setState(customAddress.getState());
2154
            customerAddress.setCountry(customAddress.getCountry());
2155
            customerAddress.setPhoneNumber(customAddress.getPhoneNumber());
2156
            customerAddressRepository.persist(customerAddress);
2157
            fofoOrder.setCustomerAddressId(customerAddress.getId());
2158
 
2159
        }
32145 tejbeer 2160
        CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());
2161
        if (!customerAddress.getState().equalsIgnoreCase(customCustomer.getAddress().getState())) {
2162
            List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
2163
            resetTaxation(fofoOrder.getFofoId(), customerAddress, fofoOrderItems);
2164
        }
2165
        this.setCustomerAddress(customerAddress, customCustomer.getAddress());
2166
        fofoOrder.setCustomerGstNumber(customCustomer.getGstNumber());
2167
    }
23638 amit.gupta 2168
 
34338 ranu 2169
    private boolean isNullOrEmpty(String str) {
2170
        return str == null || str.trim().isEmpty();
2171
    }
2172
 
33665 ranu 2173
    private void resetTaxation(int fofoId, CustomerAddress customerAddress, List<FofoOrderItem> fofoOrderItems) throws
2174
            ProfitMandiBusinessException {
32145 tejbeer 2175
        int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoId);
23650 amit.gupta 2176
 
32145 tejbeer 2177
        Address retailerAddress = addressRepository.selectById(retailerAddressId);
24275 amit.gupta 2178
 
32145 tejbeer 2179
        Integer stateId = null;
2180
        if (customerAddress.getState().equalsIgnoreCase(retailerAddress.getState())) {
2181
            try {
2182
                stateId = Long.valueOf(stateRepository.selectByName(customerAddress.getState()).getId()).intValue();
2183
            } catch (Exception e) {
2184
                LOGGER.error("Unable to get state rates");
2185
            }
2186
        }
2187
        List<Integer> itemIds = fofoOrderItems.stream().map(x -> x.getItemId()).collect(Collectors.toList());
2188
        final Map<Integer, GstRate> gstRates;
2189
        if (stateId != null) {
2190
            gstRates = stateGstRateRepository.getStateTaxRate(itemIds, stateId);
2191
        } else {
2192
            gstRates = stateGstRateRepository.getIgstTaxRate(itemIds);
2193
        }
2194
        for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
2195
            GstRate rate = gstRates.get(fofoOrderItem.getItemId());
2196
            fofoOrderItem.setCgstRate(rate.getCgstRate());
2197
            fofoOrderItem.setSgstRate(rate.getSgstRate());
2198
            fofoOrderItem.setIgstRate(rate.getIgstRate());
2199
        }
2200
    }
2201
    @Override
33665 ranu 2202
    public CustomerCreditNote badReturn(int fofoId, FoiBadReturnRequest foiBadReturnRequest) throws
2203
            ProfitMandiBusinessException {
34141 tejus.loha 2204
        return this.badReturn(null, fofoId, foiBadReturnRequest);
2205
    }
2206
    @Override
2207
    public CustomerCreditNote badReturn(String loginMail,int fofoId, FoiBadReturnRequest foiBadReturnRequest) throws
2208
            ProfitMandiBusinessException {
32145 tejbeer 2209
        FofoOrderItem foi = fofoOrderItemRepository.selectById(foiBadReturnRequest.getFofoOrderItemId());
2210
        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(foi.getOrderId());
2211
        if (fofoOrder.getFofoId() != fofoId) {
2212
            throw new ProfitMandiBusinessException("Partner Auth", "", "Invalid Order");
2213
        }
2214
        int billedQty = foi.getQuantity() - customerReturnItemRepository.selectAllByOrderItemId(foi.getId()).size();
2215
        if (foiBadReturnRequest.getMarkedBadArr().size() > billedQty) {
2216
            throw new ProfitMandiBusinessException("Cant bad return more than what is billed", "", "Invalid Quantity");
2217
        }
2218
        List<CustomerReturnItem> customerReturnItems = new ArrayList<>();
2219
        for (BadReturnRequest badReturnRequest : foiBadReturnRequest.getMarkedBadArr()) {
2220
            CustomerReturnItem customerReturnItem = new CustomerReturnItem();
2221
            customerReturnItem.setFofoId(fofoId);
2222
            customerReturnItem.setFofoOrderItemId(foiBadReturnRequest.getFofoOrderItemId());
2223
            customerReturnItem.setFofoOrderId(fofoOrder.getId());
2224
            customerReturnItem.setRemarks(badReturnRequest.getRemarks());
2225
            customerReturnItem.setInventoryItemId(badReturnRequest.getInventoryItemId());
2226
            customerReturnItem.setQuantity(1);
2227
            customerReturnItem.setType(ReturnType.BAD);
2228
            // customerReturnItemRepository.persist(customerReturnItem);
2229
            inventoryService.saleReturnInventoryItem(customerReturnItem);
2230
            customerReturnItems.add(customerReturnItem);
2231
        }
2232
        CustomerCreditNote creditNote = generateCreditNote(fofoOrder, customerReturnItems);
2233
        for (CustomerReturnItem customerReturnItem : customerReturnItems) {
2234
            purchaseReturnService.returnInventoryItem(fofoId, false, customerReturnItem.getInventoryItemId(), ReturnType.BAD);
2235
        }
2236
        // This should cancel the order
2237
        fofoOrder.setCancelledTimestamp(LocalDateTime.now());
2238
        this.reverseScheme(fofoOrder);
2239
        return creditNote;
2240
    }
23638 amit.gupta 2241
 
33665 ranu 2242
    private CustomerCreditNote generateCreditNote(FofoOrder
2243
                                                          fofoOrder, List<CustomerReturnItem> customerReturnItems) throws ProfitMandiBusinessException {
24275 amit.gupta 2244
 
32145 tejbeer 2245
        InvoiceNumberGenerationSequence sequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoOrder.getFofoId());
2246
        sequence.setCreditNoteSequence(sequence.getCreditNoteSequence() + 1);
2247
        invoiceNumberGenerationSequenceRepository.persist(sequence);
24275 amit.gupta 2248
 
32145 tejbeer 2249
        String creditNoteNumber = sequence.getPrefix() + "/" + sequence.getCreditNoteSequence();
2250
        CustomerCreditNote creditNote = new CustomerCreditNote();
2251
        creditNote.setCreditNoteNumber(creditNoteNumber);
2252
        creditNote.setFofoId(fofoOrder.getFofoId());
2253
        creditNote.setFofoOrderId(fofoOrder.getId());
2254
        creditNote.setFofoOrderItemId(customerReturnItems.get(0).getFofoOrderItemId());
2255
        creditNote.setSettlementType(SettlementType.UNSETTLED);
2256
        customerCreditNoteRepository.persist(creditNote);
24275 amit.gupta 2257
 
32145 tejbeer 2258
        for (CustomerReturnItem customerReturnItem : customerReturnItems) {
2259
            customerReturnItem.setCreditNoteId(creditNote.getId());
2260
            customerReturnItemRepository.persist(customerReturnItem);
2261
        }
2262
        // this.returnInventoryItems(inventoryItems, debitNote);
23655 amit.gupta 2263
 
32145 tejbeer 2264
        return creditNote;
2265
    }
23655 amit.gupta 2266
 
32145 tejbeer 2267
    @Override
2268
    public CreditNotePdfModel getCreditNotePdfModel(int customerCreditNoteId) throws ProfitMandiBusinessException {
2269
        CustomerCreditNote creditNote = customerCreditNoteRepository.selectById(customerCreditNoteId);
2270
        return getCreditNotePdfModel(creditNote);
2271
    }
24275 amit.gupta 2272
 
33665 ranu 2273
    private CreditNotePdfModel getCreditNotePdfModel(CustomerCreditNote creditNote) throws
2274
            ProfitMandiBusinessException {
32145 tejbeer 2275
        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(creditNote.getFofoOrderId());
2276
        List<CustomerReturnItem> customerReturnItems = customerReturnItemRepository.selectAllByCreditNoteId(creditNote.getId());
33090 amit.gupta 2277
        CustomRetailer customRetailer = retailerService.getFofoRetailer(fofoOrder.getFofoId());
2278
        CustomCustomer customCustomer = getCustomCustomer(fofoOrder, customRetailer.getAddress());
24275 amit.gupta 2279
 
33298 amit.gupta 2280
        List<CustomOrderItem> customerFofoOrderItems = new ArrayList<>();
23655 amit.gupta 2281
 
32145 tejbeer 2282
        FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(creditNote.getFofoOrderItemId());
2283
        float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
2284
        float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
2285
        float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
24275 amit.gupta 2286
 
32145 tejbeer 2287
        CustomOrderItem customFofoOrderItem = new CustomOrderItem();
2288
        customFofoOrderItem.setAmount(customerReturnItems.size() * (taxableSellingPrice - taxableDiscountPrice));
2289
        customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
24275 amit.gupta 2290
 
32145 tejbeer 2291
        if (ItemType.SERIALIZED.equals(itemRepository.selectById(fofoOrderItem.getItemId()).getType())) {
2292
            Set<Integer> inventoryItemIds = customerReturnItems.stream().map(x -> x.getInventoryItemId()).collect(Collectors.toSet());
2293
            List<String> serialNumbers = inventoryItemRepository.selectByIds(inventoryItemIds).stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());
2294
            customFofoOrderItem.setDescription(
2295
                    customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
2296
        }
23638 amit.gupta 2297
 
32145 tejbeer 2298
        customFofoOrderItem.setRate(taxableSellingPrice);
2299
        customFofoOrderItem.setDiscount(taxableDiscountPrice);
2300
        customFofoOrderItem.setQuantity(customerReturnItems.size());
2301
        customFofoOrderItem.setNetAmount(
2302
                (fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * customFofoOrderItem.getQuantity());
29707 tejbeer 2303
 
32145 tejbeer 2304
        float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
2305
        float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
2306
        float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
2307
        LOGGER.info("fofoOrderItem - {}", fofoOrderItem);
2308
        customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
2309
        customFofoOrderItem.setIgstAmount(igstAmount);
2310
        customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
2311
        customFofoOrderItem.setCgstAmount(cgstAmount);
2312
        customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
2313
        customFofoOrderItem.setSgstAmount(sgstAmount);
2314
        customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
2315
        customFofoOrderItem.setOrderId(1);
2316
        customerFofoOrderItems.add(customFofoOrderItem);
29707 tejbeer 2317
 
32145 tejbeer 2318
        InvoicePdfModel pdfModel = new InvoicePdfModel();
2319
        pdfModel.setAuther("NSSPL");
2320
        pdfModel.setCustomer(customCustomer);
2321
        pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
2322
        pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));
2323
        pdfModel.setTitle("Credit Note");
2324
        pdfModel.setRetailer(customRetailer);
2325
        pdfModel.setTotalAmount(customFofoOrderItem.getNetAmount());
2326
        pdfModel.setOrderItems(customerFofoOrderItems);
29707 tejbeer 2327
 
32145 tejbeer 2328
        CreditNotePdfModel creditNotePdfModel = new CreditNotePdfModel();
2329
        creditNotePdfModel.setCreditNoteDate(FormattingUtils.formatDate(creditNote.getCreateTimestamp()));
2330
        creditNotePdfModel.setCreditNoteNumber(creditNote.getCreditNoteNumber());
2331
        creditNotePdfModel.setPdfModel(pdfModel);
2332
        return creditNotePdfModel;
2333
    }
24264 amit.gupta 2334
 
32145 tejbeer 2335
    // This will remove the order and maintain order record and reverse inventory
2336
    // and scheme
2337
    @Override
2338
    public void cancelOrder(List<String> invoiceNumbers) throws ProfitMandiBusinessException {
2339
        for (String invoiceNumber : invoiceNumbers) {
2340
            // Cancel only when not cancelled
2341
            FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
2342
            if (fofoOrder.getCancelledTimestamp() == null) {
2343
                fofoOrder.setCancelledTimestamp(LocalDateTime.now());
2344
                PaymentOptionTransaction paymentTransaction = new PaymentOptionTransaction();
2345
                paymentTransaction.setAmount(-fofoOrder.getTotalAmount());
2346
                paymentTransaction.setFofoId(fofoOrder.getFofoId());
2347
                paymentTransaction.setReferenceId(fofoOrder.getId());
2348
                paymentTransaction.setReferenceType(PaymentOptionReferenceType.ORDER);
2349
                paymentTransaction.setPaymentOptionId(1);
2350
                paymentOptionTransactionRepository.persist(paymentTransaction);
31030 amit.gupta 2351
 
32145 tejbeer 2352
                List<FofoOrderItem> fois = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
2353
                if (fois.size() > 0) {
2354
                    List<InventoryItem> inventoryItems = new ArrayList<>();
2355
                    fois.stream().forEach(x -> {
2356
                        x.getFofoLineItems().stream().forEach(y -> {
2357
                            inventoryService.rollbackInventory(y.getInventoryItemId(), y.getQuantity(), fofoOrder.getFofoId());
2358
                            inventoryItems.add(inventoryItemRepository.selectById(y.getInventoryItemId()));
2359
                        });
2360
                    });
2361
                    // if(invoice)
2362
                    this.reverseScheme(fofoOrder);
2363
                }
2364
                insuranceService.cancelInsurance(fofoOrder);
2365
            }
2366
        }
2367
    }
31030 amit.gupta 2368
 
32145 tejbeer 2369
    @Override
2370
    public void reverseScheme(FofoOrder fofoOrder) throws ProfitMandiBusinessException {
2371
        String reversalReason = "Order Rolledback/Cancelled/Returned for Invoice #" + fofoOrder.getInvoiceNumber();
2372
        List<FofoOrderItem> fois = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
2373
        Set<Integer> inventoryItemIds = fois.stream().flatMap(x -> x.getFofoLineItems().stream().map(y -> y.getInventoryItemId())).collect(Collectors.toSet());
2374
        List<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIds);
34319 amit.gupta 2375
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, SchemeType.OUT_SCHEME_TYPES);
32145 tejbeer 2376
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.INVESTMENT));
34319 amit.gupta 2377
        //schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.ACTIVATION));
32145 tejbeer 2378
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.SPECIAL_SUPPORT));
31030 amit.gupta 2379
 
32145 tejbeer 2380
    }
24271 amit.gupta 2381
 
32145 tejbeer 2382
    @Override
2383
    public void reverseActivationScheme(List<Integer> inventoryItemIds) throws ProfitMandiBusinessException {
2384
        List<InventoryItem> inventoryItems = inventoryItemRepository.selectAllByIds(inventoryItemIds);
2385
        for (InventoryItem inventoryItem : inventoryItems) {
2386
            List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByInventoryItemId(inventoryItem.getId());
2387
            FofoLineItem fofoLineItem = fofoLineItems.get(0);
2388
            FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(fofoLineItem.getFofoOrderItemId());
2389
            FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(fofoOrderItem.getOrderId());
2390
            String reversalReason = "Scheme rolled back as activation date is invalid for imei " + inventoryItem.getSerialNumber();
34319 amit.gupta 2391
            //schemeService.reverseSchemes(Arrays.asList(inventoryItem), fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.ACTIVATION));
32145 tejbeer 2392
            schemeService.reverseSchemes(Arrays.asList(inventoryItem), fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.SPECIAL_SUPPORT));
27083 amit.gupta 2393
 
32145 tejbeer 2394
        }
24271 amit.gupta 2395
 
32145 tejbeer 2396
    }
24271 amit.gupta 2397
 
32145 tejbeer 2398
    @Override
2399
    public float getSales(int fofoId, LocalDateTime startDate, LocalDateTime endDate) {
2400
        Float sales = fofoOrderRepository.selectSaleSumGroupByFofoIds(startDate, endDate).get(fofoId);
2401
        return sales == null ? 0f : sales;
2402
    }
24271 amit.gupta 2403
 
32145 tejbeer 2404
    @Override
2405
    public LocalDateTime getMaxSalesDate(int fofoId, LocalDateTime startDate, LocalDateTime endDate) {
2406
        LocalDateTime dateTime = fofoOrderRepository.selectMaxSaleDateGroupByFofoIds(startDate, endDate).get(fofoId);
2407
        return dateTime;
2408
    }
25101 amit.gupta 2409
 
32145 tejbeer 2410
    @Override
2411
    // Only being used internally
2412
    public float getSales(int fofoId, LocalDate onDate) {
2413
        LocalDateTime startTime = LocalDateTime.of(onDate, LocalTime.MIDNIGHT);
2414
        LocalDateTime endTime = LocalDateTime.of(onDate, LocalTime.MIDNIGHT).plusDays(1);
2415
        return this.getSales(fofoId, startTime, endTime);
2416
    }
24917 tejbeer 2417
 
32145 tejbeer 2418
    @Override
2419
    public float getSales(LocalDateTime onDate) {
2420
        // TODO Auto-generated method stub
2421
        return 0;
2422
    }
28166 tejbeer 2423
 
32145 tejbeer 2424
    @Override
2425
    public float getSales(LocalDateTime startDate, LocalDateTime endDate) {
2426
        // TODO Auto-generated method stub
2427
        return 0;
2428
    }
28166 tejbeer 2429
 
32145 tejbeer 2430
    @Override
2431
    public boolean notifyColorChange(int orderId, int itemId) throws ProfitMandiBusinessException {
2432
        Order order = orderRepository.selectById(orderId);
2433
        saholicInventoryService.reservationCountByColor(itemId, order);
28166 tejbeer 2434
 
32145 tejbeer 2435
        order.getLineItem().setItemId(itemId);
2436
        Item item = itemRepository.selectById(itemId);
2437
        order.getLineItem().setColor(item.getColor());
2438
        return true;
2439
    }
28166 tejbeer 2440
 
32145 tejbeer 2441
    @Override
2442
    public FofoOrder getOrderByInventoryItemId(int inventoryItemId) throws Exception {
2443
        List<FofoLineItem> lineItems = fofoLineItemRepository.selectByInventoryItemId(inventoryItemId);
2444
        if (lineItems.size() > 0) {
2445
            FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(lineItems.get(0).getFofoOrderItemId());
2446
            fofoOrderItem.setFofoLineItems(new HashSet<>(lineItems));
2447
            FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(fofoOrderItem.getOrderId());
2448
            fofoOrder.setOrderItem(fofoOrderItem);
2449
            return fofoOrder;
2450
        } else {
2451
            throw new Exception(String.format("Could not find inventoryItemId - %s", inventoryItemId));
2452
        }
2453
    }
28166 tejbeer 2454
 
32145 tejbeer 2455
    @Override
2456
    public Map<Integer, Long> carryBagCreditCount(int fofoId) throws ProfitMandiBusinessException {
28166 tejbeer 2457
 
32145 tejbeer 2458
        FofoStore fs = fofoStoreRepository.selectByRetailerId(fofoId);
2459
        LocalDateTime lastCredit = fs.getBagsLastCredited();
2460
        /*
2461
         * long carryBagCount = 0; List<FofoOrder> fofoOrders =
2462
         * fofoOrderRepository.selectByFofoIdBetweenCreatedTimeStamp(fofoId,
2463
         * lastCredit.atStartOfDay(), LocalDate.now().plusDays(1).atStartOfDay()); for
2464
         * (FofoOrder fo : fofoOrders) { carryBagCount +=
2465
         * fofoOrderItemRepository.selectByOrderId(fo.getId()).stream() .filter(x ->
2466
         * x.getSellingPrice() >= 12000).count();
2467
         *
2468
         * }
2469
         */
28166 tejbeer 2470
 
32145 tejbeer 2471
        Session session = sessionFactory.getCurrentSession();
2472
        CriteriaBuilder cb = session.getCriteriaBuilder();
2473
 
2474
        CriteriaQuery<SimpleEntry> query = cb.createQuery(SimpleEntry.class);
2475
        Root<FofoOrder> fofoOrder = query.from(FofoOrder.class);
2476
        Root<FofoOrderItem> fofoOrderItem = query.from(FofoOrderItem.class);
2477
        Root<TagListing> tagListingRoot = query.from(TagListing.class);
2478
        Root<Item> itemRoot = query.from(Item.class);
2479
 
2480
        Predicate p2 = cb.between(fofoOrder.get(ProfitMandiConstants.CREATE_TIMESTAMP), lastCredit, LocalDate.now().atStartOfDay());
2481
        Predicate p3 = cb.isNull(fofoOrder.get("cancelledTimestamp"));
2482
        Predicate joinPredicate = cb.and(
2483
                cb.equal(fofoOrder.get(ProfitMandiConstants.ID), fofoOrderItem.get(ProfitMandiConstants.ORDER_ID)), cb.equal(fofoOrderItem.get("itemId"), tagListingRoot.get("itemId")), cb.equal(itemRoot.get("id"), tagListingRoot.get("itemId")), cb.equal(fofoOrder.get(ProfitMandiConstants.FOFO_ID), fofoId));
2484
        ItemCriteria itemCriteria = new ItemCriteria();
2485
        itemCriteria.setBrands(mongoClient.getMongoBrands(fofoId, null, 3).stream().map(x -> (String) x.get("name")).collect(Collectors.toList()));
2486
        float startValue = 12000;
2487
        itemCriteria.setStartPrice(startValue);
2488
        itemCriteria.setEndPrice(0);
2489
        itemCriteria.setFeaturedPhone(false);
2490
        itemCriteria.setSmartPhone(true);
2491
        itemCriteria.setCatalogIds(new ArrayList<>());
2492
        itemCriteria.setExcludeCatalogIds(new ArrayList<>());
2493
        Predicate itemPredicate = itemRepository.getItemPredicate(itemCriteria, cb, itemRoot, tagListingRoot.get("itemId"), tagListingRoot.get("sellingPrice"));
2494
        Predicate finalPredicate = cb.and(itemPredicate, p2, p3, joinPredicate);
2495
        query = query.multiselect(fofoOrder.get(ProfitMandiConstants.FOFO_ID), cb.count(fofoOrder)).where(finalPredicate).groupBy(fofoOrder.get(ProfitMandiConstants.FOFO_ID));
2496
        List<SimpleEntry> simpleEntries = session.createQuery(query).getResultList();
2497
        Map<Integer, Long> returnMap = new HashMap<>();
2498
 
2499
        for (SimpleEntry simpleEntry : simpleEntries) {
2500
            returnMap.put((Integer) simpleEntry.getKey(), (Long) simpleEntry.getValue());
2501
        }
2502
        return returnMap;
2503
 
2504
    }
32607 ranu 2505
 
2506
    @Override
2507
    public void createMissingScratchOffers() {
2508
        List<FofoOrder> fofoOrders = fofoOrderRepository.selectFromSaleDate(LocalDate.of(2023, 11, 6).atStartOfDay());
2509
        for (FofoOrder fofoOrder : fofoOrders) {
2510
            if (fofoOrder.getCancelledTimestamp() == null) { // Check if cancelled_timestamp is not null
2511
                try {
2512
                    this.createScratchOffer(fofoOrder.getFofoId(), fofoOrder.getInvoiceNumber(), fofoOrder.getCustomerId());
2513
                } catch (Exception e) {
2514
                    LOGGER.error("Error while processing missing scratch offer invoice orderId", fofoOrder.getId());
2515
                }
2516
            }
2517
        }
2518
    }
32724 amit.gupta 2519
 
2520
    @Override
33665 ranu 2521
    public boolean refundOrder(int orderId, String refundedBy, String refundReason) throws
2522
            ProfitMandiBusinessException {
32724 amit.gupta 2523
        /*def refund_order(order_id, refunded_by, reason):
2524
        """
2525
        If the order is in RTO_RECEIVED_PRESTINE, DOA_CERT_VALID or DOA_CERT_INVALID state, it does the following:
2526
            1. Creates a refund request for batch processing.
2527
            2. Creates a return order for the warehouse executive to return the shipped material.
2528
            3. Marks the current order as RTO_REFUNDED, DOA_VALID_REFUNDED or DOA_INVALID_REFUNDED final states.
2529
 
2530
        If the order is in SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2531
            1. Creates a refund request for batch processing.
2532
            2. Cancels the reservation of the item in the warehouse.
2533
            3. Marks the current order as the REFUNDED final state.
2534
 
2535
        For all COD orders, if the order is in INIT, SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2536
            1. Cancels the reservation of the item in the warehouse.
2537
            2. Marks the current order as CANCELED.
2538
 
2539
        In all cases, it updates the reason for cancellation or refund and the person who performed the action.
2540
 
2541
        Returns True if it is successful, False otherwise.
2542
 
2543
        Throws an exception if the order with the given id couldn't be found.
2544
 
2545
        Parameters:
2546
         - order_id
2547
         - refunded_by
2548
         - reason
2549
        """
2550
        LOGGER.info("Refunding order id: {}", orderId);
2551
        Order order = orderRepository.selectById(orderId);
2552
 
2553
        if order.cod:
2554
        logging.info("Refunding COD order with status " + str(order.status))
2555
        status_transition = refund_status_transition
2556
        if order.status not in status_transition.keys():
2557
        raise TransactionServiceException(114, "This order can't be refunded")
2558
 
2559
        if order.status in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
2560
        __update_inventory_reservation(order, refund=True)
2561
        order.statusDescription = "Order Cancelled"
2562
            #Shipment Id and Airway Bill No should be none in case of Cancellation
2563
        order.logisticsTransactionId = None
2564
        order.tracking_id = None
2565
        order.airwaybill_no = None
2566
        elif order.status == OrderStatus.BILLED:
2567
        __create_return_order(order)
2568
        order.statusDescription = "Order Cancelled"
2569
        elif order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT]:
2570
        if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2571
        __create_return_order(order)
2572
        order.statusDescription = "RTO Refunded"
2573
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
2574
            #__create_return_order(order)
2575
        order.statusDescription = "Lost in Transit Refunded"
2576
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
2577
        if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2578
        __create_return_order(order)
2579
        __create_refund(order, 0, 'Should be unreachable for now')
2580
        order.statusDescription = "DOA Refunded"
2581
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
2582
        if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2583
        __create_return_order(order)
2584
        __create_refund(order, 0, 'Should be unreachable for now')
2585
        order.statusDescription = "Return Refunded"
2586
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
2587
        if order.previousStatus in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
2588
        __update_inventory_reservation(order, refund=True)
2589
        order.statusDescription = "Order Cancelled on customer request"
2590
        elif order.previousStatus == OrderStatus.BILLED:
2591
        __create_return_order(order)
2592
        order.statusDescription = "Order Cancelled on customer request"
2593
        order.received_return_timestamp = datetime.datetime.now()
2594
    else:
2595
        status_transition = {OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,
2596
                OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,
2597
                OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,
2598
                OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,
2599
                OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,
2600
                OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,
2601
                OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,
2602
                OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,
2603
                OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,
2604
                OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,
2605
                OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,
2606
                OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,
2607
                OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2608
                OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2609
                OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2610
                OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2611
                OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2612
                OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2613
                OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2614
                OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST,
2615
                OrderStatus.PAYMENT_FLAGGED : OrderStatus.PAYMENT_FLAGGED_DENIED
2616
                     }
2617
        if order.status not in status_transition.keys():
2618
        raise TransactionServiceException(114, "This order can't be refunded")
2619
 
2620
        if order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT] :
2621
        if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2622
        __create_return_order(order)
2623
        __create_refund(order, order.wallet_amount, 'Order #{0} is RTO refunded'.format(order.id))
2624
        order.statusDescription = "RTO Refunded"
2625
            #Start:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013
2626
        try:
2627
        crmServiceClient = CRMClient().get_client()
2628
        ticket =Ticket()
2629
        activity = Activity()
2630
 
2631
        description = "Creating Ticket for " + order.statusDescription + " Order"
2632
        ticket.creatorId = 1
2633
        ticket.assigneeId = 34
2634
        ticket.category = TicketCategory.RTO_REFUND
2635
        ticket.priority = TicketPriority.MEDIUM
2636
        ticket.status = TicketStatus.OPEN
2637
        ticket.description = description
2638
        ticket.orderId = order.id
2639
 
2640
        activity.creatorId = 1
2641
        activity.ticketAssigneeId = ticket.assigneeId
2642
        activity.type = ActivityType.OTHER
2643
        activity.description = description
2644
        activity.ticketCategory = ticket.category
2645
        activity.ticketDescription = ticket.description
2646
        activity.ticketPriority = ticket.priority
2647
        activity.ticketStatus = ticket.status
2648
 
2649
        ticket.customerId= order.customer_id
2650
        ticket.customerEmailId = order.customer_email
2651
        ticket.customerMobileNumber = order.customer_mobilenumber
2652
        ticket.customerName = order.customer_name
2653
        activity.customerId = ticket.customerId
2654
        activity.customerEmailId = order.customer_email
2655
        activity.customerMobileNumber = order.customer_mobilenumber
2656
        activity.customerName = order.customer_name
2657
 
2658
        crmServiceClient.insertTicket(ticket, activity)
2659
 
2660
        except:
2661
        print "Ticket for RTO Refund is not created."
2662
            #End:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013
2663
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
2664
            #__create_return_order(order)
2665
        __create_refund(order, order.wallet_amount, 'Order #{0} is Lost in Transit'.format(order.id))
2666
        order.statusDescription = "Lost in Transit Refunded"
2667
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
2668
        if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2669
        __create_return_order(order)
2670
        __create_refund(order, 0, 'This should be unreachable')
2671
        order.statusDescription = "DOA Refunded"
2672
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
2673
        if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2674
        __create_return_order(order)
2675
        __create_refund(order, 0, 'This should be unreachable')
2676
        order.statusDescription = "Return Refunded"
2677
        elif order.status in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
2678
        __update_inventory_reservation(order, refund=True)
2679
        order.statusDescription = "Order Refunded"
2680
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
2681
        if order.previousStatus in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.PAYMENT_FLAGGED, OrderStatus.ACCEPTED]:
2682
        __update_inventory_reservation(order, refund=True)
2683
        order.statusDescription = "Order Cancelled on customer request"
2684
        elif order.previousStatus == OrderStatus.BILLED:
2685
        __create_refund(order, order.wallet_amount,  'Order #{0} Cancelled on customer request'.format(order.id))
2686
        order.statusDescription = "Order Cancelled on customer request"
2687
 
2688
        elif order.status == OrderStatus.PAYMENT_FLAGGED:
2689
        __update_inventory_reservation(order, refund=True)
2690
        order.statusDescription = "Order Cancelled due to payment flagged"
2691
 
2692
    # For orders that are cancelled after being billed, we need to scan in the scanned out
2693
    # inventory item and change availability accordingly
2694
        inventoryClient = InventoryClient().get_client()
2695
        warehouse = inventoryClient.getWarehouse(order.warehouse_id)
2696
        if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
2697
        #Now BILLED orders can also be refunded directly with low inventory cancellations
2698
        if order.status in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH]:
2699
        __create_refund(order, order.wallet_amount, reason)
2700
        if order.status in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH] or (order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED and order.previousStatus in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH]):
2701
        lineitem = order.lineitems[0]
2702
        catalogClient = CatalogClient().get_client()
2703
        item = catalogClient.getItem(lineitem.item_id)
2704
        warehouseClient = WarehouseClient().get_client()
2705
        if warehouse.billingType == BillingType.OURS:
2706
        if ItemType.SERIALIZED == item.type:
2707
        for serial_number in str(lineitem.serial_number).split(','):
2708
        warehouseClient.scanSerializedItemForOrder(serial_number, ScanType.SALE_RET, order.id, order.fulfilmentWarehouseId, 1, order.warehouse_id)
2709
                else:
2710
        warehouseClient.scanForOrder(None, ScanType.SALE_RET, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2711
        if warehouse.billingType == BillingType.OURS_EXTERNAL:
2712
        warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)
2713
        if order.freebieItemId:
2714
        warehouseClient.scanfreebie(order.id, order.freebieItemId, 0, ScanType.SALE_RET)
2715
 
2716
        order.status = status_transition[order.status]
2717
        order.statusDescription = OrderStatus._VALUES_TO_NAMES[order.status]
2718
        order.refund_timestamp = datetime.datetime.now()
2719
        order.refunded_by = refunded_by
2720
        order.refund_reason = reason
2721
    #to re evaluate the shipping charge if any order is being cancelled.
2722
    #_revaluate_shiping(order_id)
2723
        session.commit()
2724
        return True*/
2725
        return true;
2726
    }
2727
 
2728
    @Autowired
2729
    DebitNoteRepository debitNoteRepository;
2730
 
2731
    //initiate refund only if the stock is returned
2732
 
25724 amit.gupta 2733
}