Subversion Repositories SmartDukaan

Rev

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

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