Subversion Repositories SmartDukaan

Rev

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