Subversion Repositories SmartDukaan

Rev

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