Subversion Repositories SmartDukaan

Rev

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

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