Subversion Repositories SmartDukaan

Rev

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