Subversion Repositories SmartDukaan

Rev

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