Subversion Repositories SmartDukaan

Rev

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

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