Subversion Repositories SmartDukaan

Rev

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