Subversion Repositories SmartDukaan

Rev

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