Subversion Repositories SmartDukaan

Rev

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

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