Subversion Repositories SmartDukaan

Rev

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

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