Subversion Repositories SmartDukaan

Rev

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