Subversion Repositories SmartDukaan

Rev

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