Subversion Repositories SmartDukaan

Rev

Rev 33679 | Rev 33718 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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