Subversion Repositories SmartDukaan

Rev

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