Subversion Repositories SmartDukaan

Rev

Rev 33436 | Rev 33520 | 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;
33399 ranu 267
        int changedTotalBillAmount=0;
268
        for(CustomPaymentOption cpo : createOrderRequest.getPaymentOptions()){
269
            changedTotalBillAmount += cpo.getAmount();
270
        }
32145 tejbeer 271
        for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
33399 ranu 272
            if(customFofoOrderItem.getPoiId() > 0){
273
                PendingOrderItem pendingOrderItem = pendingOrderItemRepository.selectById(customFofoOrderItem.getPoiId());
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
                }
277
                if(pendingOrderItem.getQuantity() > customFofoOrderItem.getQuantity()){
33436 ranu 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 {
289
                totalAmount = totalAmount + customFofoOrderItem.getSellingPrice() * customFofoOrderItem.getQuantity();
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 {
33436 ranu 354
                            Map<String, List<MobileInsurancePlan>> mobileInsurancePlanMap = insuranceService.getAllPlans(item.getId(), im.getDeviceSellingPrice(),false);
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);
33399 ranu 575
            for(CustomFofoOrderItem cfoi : createOrderRequest.getFofoOrderItems()){
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
 
32420 amit.gupta 1439
    private void validateDpPrice(int fofoId, Map<Integer, PriceModel> itemIdMopPriceMap, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException {
1440
        if (pricingService.getMopVoilatedRetailerIds().contains(fofoId)) return;
32145 tejbeer 1441
        for (Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoLineItemMap.entrySet()) {
1442
            int itemId = entry.getKey();
1443
            CustomFofoOrderItem customFofoOrderItem = entry.getValue();
1444
            LOGGER.info("CustomFofoOrderItem -- {}", customFofoOrderItem);
1445
            PriceModel priceModel = itemIdMopPriceMap.get(itemId);
1446
            Item item = itemRepository.selectById(itemId);
1447
            if (!item.getBrand().equals("Live Demo") && (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) {
1448
                if (Utils.compareFloat(priceModel.getPrice(), customFofoOrderItem.getSellingPrice() + customFofoOrderItem.getDiscountAmount()) > 0) {
1449
                    throw new ProfitMandiBusinessException("Selling Price for ", item.getItemDescription(), "FFORDR_1010");
1450
                }
1451
            } else {
1452
                if (!item.getBrand().equals("Live Demo") && priceModel.getPurchasePrice() > customFofoOrderItem.getSellingPrice()) {
1453
                    throw new ProfitMandiBusinessException("Selling Price", itemRepository.selectById(itemId).getItemDescription(), "Selling Price should not be less than DP");
1454
                }
1455
            }
1456
        }
1457
    }
24275 amit.gupta 1458
 
32420 amit.gupta 1459
    private void validateMopPrice(int fofoId, Map<Integer, PriceModel> itemIdMopPriceMap, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException {
1460
        if (pricingService.getMopVoilatedRetailerIds().contains(fofoId)) return;
32145 tejbeer 1461
        Map<Integer, Float> invalidMopItemIdPriceMap = new HashMap<>();
1462
        for (Map.Entry<Integer, PriceModel> entry : itemIdMopPriceMap.entrySet()) {
1463
            CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoLineItemMap.get(entry.getKey());
1464
            Item item = itemRepository.selectById(customFofoOrderItem.getItemId());
1465
            if (!(item.getBrand().equals("Live Demo") || item.getCategoryId() != ProfitMandiConstants.MOBILE_CATEGORY_ID || item.getCategoryId() != ProfitMandiConstants.TABLET_CATEGORY_ID) && customFofoOrderItem.getSellingPrice() + customFofoOrderItem.getDiscountAmount() < entry.getValue().getPrice()) {
1466
                invalidMopItemIdPriceMap.put(entry.getKey(), customFofoOrderItem.getSellingPrice());
1467
            }
1468
        }
23650 amit.gupta 1469
 
32145 tejbeer 1470
        if (!invalidMopItemIdPriceMap.isEmpty()) {
1471
            LOGGER.error("Invalid itemIds selling prices{} should be greater than mop prices {}", invalidMopItemIdPriceMap, itemIdMopPriceMap);
1472
            throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidMopItemIdPriceMap, "FFORDR_1010");
1473
        }
23650 amit.gupta 1474
 
32145 tejbeer 1475
    }
23650 amit.gupta 1476
 
32145 tejbeer 1477
    private void updateInventoryItemsAndScanRecord(Set<InventoryItem> inventoryItems, int fofoId, Map<Integer, Integer> inventoryItemQuantityUsed, int fofoOrderId) {
1478
        for (InventoryItem inventoryItem : inventoryItems) {
1479
            inventoryItem.setLastScanType(ScanType.SALE);
33087 amit.gupta 1480
            inventoryItem.setUpdateTimestamp(LocalDateTime.now());
32145 tejbeer 1481
            ScanRecord scanRecord = new ScanRecord();
1482
            scanRecord.setInventoryItemId(inventoryItem.getId());
1483
            scanRecord.setFofoId(fofoId);
1484
            scanRecord.setOrderId(fofoOrderId);
1485
            // correct this
1486
            scanRecord.setQuantity(inventoryItemQuantityUsed.get(inventoryItem.getId()));
1487
            scanRecord.setType(ScanType.SALE);
1488
            scanRecordRepository.persist(scanRecord);
1489
            purchaseReturnItemRepository.deleteById(inventoryItem.getId());
23650 amit.gupta 1490
 
32145 tejbeer 1491
        }
1492
    }
23650 amit.gupta 1493
 
32145 tejbeer 1494
    private void createFofoLineItem(int fofoOrderItemId, Set<InventoryItem> inventoryItems, Map<Integer, Integer> inventoryItemIdQuantityUsed) {
1495
        for (InventoryItem inventoryItem : inventoryItems) {
1496
            FofoLineItem fofoLineItem = new FofoLineItem();
1497
            fofoLineItem.setFofoOrderItemId(fofoOrderItemId);
1498
            fofoLineItem.setSerialNumber(inventoryItem.getSerialNumber());
1499
            fofoLineItem.setInventoryItemId(inventoryItem.getId());
1500
            fofoLineItem.setQuantity(inventoryItemIdQuantityUsed.get(inventoryItem.getId()));
1501
            fofoLineItemRepository.persist(fofoLineItem);
1502
        }
1503
    }
23650 amit.gupta 1504
 
32145 tejbeer 1505
    private FofoOrderItem createAndGetFofoOrderItem(CustomFofoOrderItem customFofoOrderItem, int fofoOrderId, Map<Integer, Item> itemMap, Set<InventoryItem> inventoryItems, Integer stateId) throws ProfitMandiBusinessException {
1506
        FofoOrderItem fofoOrderItem = new FofoOrderItem();
1507
        fofoOrderItem.setItemId(customFofoOrderItem.getItemId());
1508
        fofoOrderItem.setQuantity(customFofoOrderItem.getQuantity());
1509
        fofoOrderItem.setSellingPrice(customFofoOrderItem.getSellingPrice());
1510
        fofoOrderItem.setOrderId(fofoOrderId);
1511
        TagListing tl = tagListingRepository.selectByItemId(customFofoOrderItem.getItemId());
1512
        // In case listing gets removed rebill it using the selling price
1513
        if (tl != null) {
1514
            fofoOrderItem.setDp(tl.getSellingPrice());
1515
            fofoOrderItem.setMop(tl.getMop());
1516
        } else {
1517
            fofoOrderItem.setDp(customFofoOrderItem.getSellingPrice());
1518
            fofoOrderItem.setMop(customFofoOrderItem.getSellingPrice());
1519
        }
1520
        fofoOrderItem.setDiscount(customFofoOrderItem.getDiscountAmount());
24823 amit.gupta 1521
 
32145 tejbeer 1522
        Item item = itemMap.get(customFofoOrderItem.getItemId());
1523
        Map<Integer, GstRate> itemIdStateTaxRateMap = null;
1524
        if (stateId != null) {
1525
            itemIdStateTaxRateMap = stateGstRateRepository.getStateTaxRate(new ArrayList<>(itemMap.keySet()), stateId);
1526
        } else {
1527
            itemIdStateTaxRateMap = stateGstRateRepository.getIgstTaxRate(new ArrayList<>(itemMap.keySet()));
1528
        }
1529
        for (InventoryItem inventoryItem : inventoryItems) {
23650 amit.gupta 1530
 
32145 tejbeer 1531
            fofoOrderItem.setIgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getIgstRate());
23650 amit.gupta 1532
 
32145 tejbeer 1533
            fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getCgstRate());
1534
            fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getSgstRate());
27516 amit.gupta 1535
 
1536
 
32145 tejbeer 1537
            fofoOrderItem.setHsnCode(inventoryItem.getHsnCode());
1538
            break;
1539
        }
1540
        fofoOrderItem.setBrand(item.getBrand());
1541
        fofoOrderItem.setModelName(item.getModelName());
1542
        fofoOrderItem.setModelNumber(item.getModelNumber());
1543
        fofoOrderItem.setColor(item.getColor());
1544
        fofoOrderItemRepository.persist(fofoOrderItem);
1545
        return fofoOrderItem;
1546
    }
27516 amit.gupta 1547
 
32145 tejbeer 1548
    private FofoOrderItem getDummyFofoOrderItem(int itemId, int fofoOrderId, String serialNumber, Integer stateId) throws ProfitMandiBusinessException {
1549
        Item item = itemRepository.selectById(itemId);
1550
        TagListing tl = tagListingRepository.selectByItemId(itemId);
1551
        FofoOrderItem fofoOrderItem = new FofoOrderItem();
1552
        fofoOrderItem.setItemId(itemId);
1553
        fofoOrderItem.setQuantity(1);
1554
        fofoOrderItem.setSellingPrice(tl.getMop());
1555
        fofoOrderItem.setOrderId(fofoOrderId);
1556
        // In case listing gets removed rebill it using the selling price
1557
        fofoOrderItem.setDp(tl.getSellingPrice());
1558
        fofoOrderItem.setMop(tl.getMop());
1559
        fofoOrderItem.setDiscount(0);
27516 amit.gupta 1560
 
32145 tejbeer 1561
        Map<Integer, GstRate> itemIdStateTaxRateMap = null;
1562
        if (stateId != null) {
1563
            itemIdStateTaxRateMap = stateGstRateRepository.getStateTaxRate(Arrays.asList(itemId), stateId);
1564
        } else {
1565
            itemIdStateTaxRateMap = stateGstRateRepository.getIgstTaxRate(Arrays.asList(itemId));
1566
        }
27516 amit.gupta 1567
 
32145 tejbeer 1568
        fofoOrderItem.setIgstRate(itemIdStateTaxRateMap.get(itemId).getIgstRate());
27516 amit.gupta 1569
 
32145 tejbeer 1570
        fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(itemId).getCgstRate());
1571
        fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(itemId).getSgstRate());
23650 amit.gupta 1572
 
1573
 
32145 tejbeer 1574
        fofoOrderItem.setHsnCode(item.getHsnCode());
1575
        fofoOrderItem.setBrand(item.getBrand());
1576
        fofoOrderItem.setModelName(item.getModelName());
1577
        fofoOrderItem.setModelNumber(item.getModelNumber());
1578
        fofoOrderItem.setColor(item.getColor());
23650 amit.gupta 1579
 
32145 tejbeer 1580
        Set<FofoLineItem> fofoLineItems = new HashSet<>();
1581
        FofoLineItem fli = new FofoLineItem();
1582
        fli.setQuantity(1);
1583
        fli.setSerialNumber(serialNumber);
1584
        fofoLineItems.add(fli);
1585
        fofoOrderItem.setFofoLineItems(fofoLineItems);
22859 ashik.ali 1586
 
32145 tejbeer 1587
        return fofoOrderItem;
1588
    }
22859 ashik.ali 1589
 
32145 tejbeer 1590
    private void updateCurrentInventorySnapshot(List<CurrentInventorySnapshot> currentInventorySnapshots, int fofoId, int itemId, int quantity) throws ProfitMandiBusinessException {
1591
        for (CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {
1592
            if (currentInventorySnapshot.getItemId() == itemId && currentInventorySnapshot.getFofoId() == fofoId) {
1593
                currentInventorySnapshotRepository.updateAvailabilityByItemIdAndFofoId(itemId, fofoId, currentInventorySnapshot.getAvailability() - quantity);
1594
            }
1595
        }
1596
    }
23650 amit.gupta 1597
 
32145 tejbeer 1598
    private void createPaymentOptions(FofoOrder fofoOrder, Set<CustomPaymentOption> customPaymentOptions) throws ProfitMandiBusinessException {
1599
        for (CustomPaymentOption customPaymentOption : customPaymentOptions) {
1600
            if (customPaymentOption.getAmount() > 0) {
1601
                PaymentOptionTransaction paymentOptionTransaction = new PaymentOptionTransaction();
32627 ranu 1602
                LOGGER.error("error", fofoOrder.getId());
32145 tejbeer 1603
                paymentOptionTransaction.setReferenceId(fofoOrder.getId());
1604
                paymentOptionTransaction.setPaymentOptionId(customPaymentOption.getPaymentOptionId());
1605
                paymentOptionTransaction.setReferenceType(PaymentOptionReferenceType.ORDER);
1606
                paymentOptionTransaction.setAmount(customPaymentOption.getAmount());
1607
                paymentOptionTransaction.setFofoId(fofoOrder.getFofoId());
1608
                paymentOptionTransactionRepository.persist(paymentOptionTransaction);
1609
            }
1610
        }
1611
    }
22859 ashik.ali 1612
 
32145 tejbeer 1613
    private FofoOrder createAndGetFofoOrder(int customerId, String customerGstNumber, int fofoId, String documentNumber, float totalAmount, int customerAddressId) {
1614
        FofoOrder fofoOrder = new FofoOrder();
1615
        fofoOrder.setCustomerGstNumber(customerGstNumber);
1616
        fofoOrder.setCustomerId(customerId);
1617
        fofoOrder.setFofoId(fofoId);
1618
        fofoOrder.setInvoiceNumber(documentNumber);
1619
        fofoOrder.setTotalAmount(totalAmount);
1620
        fofoOrder.setCustomerAddressId(customerAddressId);
1621
        fofoOrderRepository.persist(fofoOrder);
1622
        return fofoOrder;
1623
    }
23650 amit.gupta 1624
 
32145 tejbeer 1625
    private void validateItemsSerializedNonSerialized(List<Item> items, Map<Integer, CustomFofoOrderItem> customFofoOrderItemMap) throws ProfitMandiBusinessException {
1626
        List<Integer> invalidItemIdSerialNumbers = new ArrayList<Integer>();
1627
        List<Integer> itemIdNonSerializedSerialNumbers = new ArrayList<Integer>();
1628
        for (Item i : items) {
1629
            CustomFofoOrderItem customFofoOrderItem = customFofoOrderItemMap.get(i.getId());
1630
            if (i.getType().equals(ItemType.SERIALIZED)) {
1631
                if (customFofoOrderItem == null || customFofoOrderItem.getSerialNumberDetails().isEmpty()) {
1632
                    invalidItemIdSerialNumbers.add(i.getId());
1633
                }
1634
            } else {
1635
                Set<String> serialNumbers = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());
1636
                if (customFofoOrderItem == null || !serialNumbers.isEmpty()) {
1637
                    itemIdNonSerializedSerialNumbers.add(i.getId());
1638
                }
1639
            }
1640
        }
23650 amit.gupta 1641
 
32145 tejbeer 1642
        if (!invalidItemIdSerialNumbers.isEmpty()) {
1643
            LOGGER.error("Invalid itemId's serialNumbers for serialized{}", invalidItemIdSerialNumbers);
1644
            // itemId's are serialized you are saying these are not serialized
1645
            throw new ProfitMandiBusinessException("invalidItemIdSerialNumbers", invalidItemIdSerialNumbers, "FFORDR_1013");
1646
        }
22859 ashik.ali 1647
 
32145 tejbeer 1648
        if (!itemIdNonSerializedSerialNumbers.isEmpty()) {
1649
            LOGGER.error("Invalid itemId's serialNumbers for non serialized{}", itemIdNonSerializedSerialNumbers);
1650
            // itemId's are non serialized you are saying these are serialized
1651
            throw new ProfitMandiBusinessException("itemIdNonSerializedSerialNumbers", itemIdNonSerializedSerialNumbers, "FFORDR_1014");
1652
        }
1653
    }
22859 ashik.ali 1654
 
32145 tejbeer 1655
    private void validateCurrentInventorySnapshotQuantities(List<CurrentInventorySnapshot> currentInventorySnapshots, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap) throws ProfitMandiBusinessException {
1656
        if (itemIdCustomFofoOrderItemMap.keySet().size() != currentInventorySnapshots.size()) {
1657
            throw new ProfitMandiBusinessException("quantiiesSize", currentInventorySnapshots.size(), "");
1658
        }
1659
        List<ItemIdQuantityAvailability> itemIdQuantityAvailabilities = new ArrayList<>(); // this is for error
1660
        LOGGER.info("currentInventorySnapshots " + currentInventorySnapshots);
1661
        LOGGER.info("CustomFofoLineItemMap {}", itemIdCustomFofoOrderItemMap);
1662
        for (CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {
1663
            CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoOrderItemMap.get(currentInventorySnapshot.getItemId());
1664
            LOGGER.info("customFofoOrderItem {}", customFofoOrderItem);
1665
            if (customFofoOrderItem.getQuantity() > currentInventorySnapshot.getAvailability()) {
1666
                ItemIdQuantityAvailability itemIdQuantityAvailability = new ItemIdQuantityAvailability();
1667
                itemIdQuantityAvailability.setItemId(customFofoOrderItem.getItemId());
1668
                Quantity quantity = new Quantity();
1669
                quantity.setAvailable(currentInventorySnapshot.getAvailability());
1670
                quantity.setRequested(customFofoOrderItem.getQuantity());
1671
                itemIdQuantityAvailability.setQuantity(quantity);
1672
                itemIdQuantityAvailabilities.add(itemIdQuantityAvailability);
1673
            }
1674
        }
22859 ashik.ali 1675
 
32145 tejbeer 1676
        if (!itemIdQuantityAvailabilities.isEmpty()) {
1677
            // itemIdQuantity request is not valid
1678
            LOGGER.error("Requested quantities should not be greater than currently available quantities {}", itemIdQuantityAvailabilities);
1679
            throw new ProfitMandiBusinessException("itemIdQuantityAvailabilities", itemIdQuantityAvailabilities, "FFORDR_1015");
1680
        }
1681
    }
22859 ashik.ali 1682
 
32145 tejbeer 1683
    private int getItemIdFromSerialNumber(Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap, String serialNumber) {
1684
        int itemId = 0;
1685
        for (Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoOrderItemMap.entrySet()) {
1686
            Set<SerialNumberDetail> serialNumberDetails = entry.getValue().getSerialNumberDetails();
1687
            for (SerialNumberDetail serialNumberDetail : serialNumberDetails) {
1688
                if (serialNumberDetail.getSerialNumber().equals(serialNumber)) {
1689
                    itemId = entry.getKey();
1690
                    break;
1691
                }
1692
            }
1693
        }
1694
        return itemId;
1695
    }
23650 amit.gupta 1696
 
32145 tejbeer 1697
    private Map<Integer, Item> toItemMap(List<Item> items) {
1698
        Function<Item, Integer> itemIdFunction = new Function<Item, Integer>() {
1699
            @Override
1700
            public Integer apply(Item item) {
1701
                return item.getId();
1702
            }
1703
        };
1704
        Function<Item, Item> itemFunction = new Function<Item, Item>() {
1705
            @Override
1706
            public Item apply(Item item) {
1707
                return item;
1708
            }
1709
        };
1710
        return items.stream().collect(Collectors.toMap(itemIdFunction, itemFunction));
1711
    }
23650 amit.gupta 1712
 
32145 tejbeer 1713
    private void setCustomerAddress(CustomerAddress customerAddress, CustomAddress customAddress) {
1714
        customerAddress.setName(customAddress.getName());
1715
        customerAddress.setLastName(customAddress.getLastName());
1716
        customerAddress.setLine1(customAddress.getLine1());
1717
        customerAddress.setLine2(customAddress.getLine2());
1718
        customerAddress.setLandmark(customAddress.getLandmark());
1719
        customerAddress.setCity(customAddress.getCity());
1720
        customerAddress.setPinCode(customAddress.getPinCode());
1721
        customerAddress.setState(customAddress.getState());
1722
        customerAddress.setCountry(customAddress.getCountry());
1723
        customerAddress.setPhoneNumber(customAddress.getPhoneNumber());
1724
    }
23650 amit.gupta 1725
 
32145 tejbeer 1726
    private CustomAddress createCustomAddress(Address address) {
1727
        CustomAddress customAddress = new CustomAddress();
1728
        customAddress.setName(address.getName());
1729
        customAddress.setLine1(address.getLine1());
1730
        customAddress.setLine2(address.getLine2());
1731
        customAddress.setLandmark(address.getLandmark());
1732
        customAddress.setCity(address.getCity());
1733
        customAddress.setPinCode(address.getPinCode());
1734
        customAddress.setState(address.getState());
1735
        customAddress.setCountry(address.getCountry());
1736
        customAddress.setPhoneNumber(address.getPhoneNumber());
1737
        return customAddress;
1738
    }
23650 amit.gupta 1739
 
32145 tejbeer 1740
    private CustomAddress createCustomAddress(CustomerAddress customerAddress) {
1741
        CustomAddress customAddress = new CustomAddress();
1742
        customAddress.setName(customerAddress.getName());
1743
        customAddress.setLastName(customerAddress.getLastName());
1744
        customAddress.setLine1(customerAddress.getLine1());
1745
        customAddress.setLine2(customerAddress.getLine2());
1746
        customAddress.setLandmark(customerAddress.getLandmark());
1747
        customAddress.setCity(customerAddress.getCity());
1748
        customAddress.setPinCode(customerAddress.getPinCode());
1749
        customAddress.setState(customerAddress.getState());
1750
        customAddress.setCountry(customerAddress.getCountry());
1751
        customAddress.setPhoneNumber(customerAddress.getPhoneNumber());
1752
        return customAddress;
1753
    }
23650 amit.gupta 1754
 
33089 amit.gupta 1755
    private CustomAddress createCustomAddressWithoutId(CustomCustomer customerAddress, CustomAddress retailerAddress) {
32627 ranu 1756
        CustomAddress customAddress = new CustomAddress();
1757
        customAddress.setName(customerAddress.getFirstName());
1758
        customAddress.setLastName(customerAddress.getLastName());
1759
        customAddress.setLine1("");
1760
        customAddress.setLine2("");
1761
        customAddress.setLandmark("");
33089 amit.gupta 1762
        customAddress.setCity(retailerAddress.getCity());
1763
        customAddress.setPinCode(retailerAddress.getPinCode());
1764
        customAddress.setState(retailerAddress.getState());
32627 ranu 1765
        customAddress.setCountry("");
1766
        customAddress.setPhoneNumber(customerAddress.getMobileNumber());
1767
        return customAddress;
1768
    }
1769
 
32145 tejbeer 1770
    private void validatePaymentOptionsAndTotalAmount(Set<CustomPaymentOption> customPaymentOptions, float totalAmount) throws ProfitMandiBusinessException {
1771
        Set<Integer> paymentOptionIds = new HashSet<>();
23650 amit.gupta 1772
 
32145 tejbeer 1773
        float calculatedAmount = 0;
1774
        for (CustomPaymentOption customPaymentOption : customPaymentOptions) {
1775
            paymentOptionIds.add(customPaymentOption.getPaymentOptionId());
1776
            calculatedAmount = calculatedAmount + customPaymentOption.getAmount();
1777
        }
1778
        if (calculatedAmount != totalAmount) {
1779
            LOGGER.warn("Error occured while validating payment options amount - {} != TotalAmount {}", calculatedAmount, totalAmount);
1780
            throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_CALCULATED_AMOUNT, calculatedAmount, "FFORDR_1016");
1781
        }
23418 ashik.ali 1782
 
32145 tejbeer 1783
        List<Integer> foundPaymentOptionIds = paymentOptionRepository.selectIdsByIds(paymentOptionIds);
1784
        if (foundPaymentOptionIds.size() != paymentOptionIds.size()) {
1785
            paymentOptionIds.removeAll(foundPaymentOptionIds);
1786
            throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_ID, paymentOptionIds, "FFORDR_1017");
1787
        }
1788
    }
25101 amit.gupta 1789
 
32145 tejbeer 1790
    @Override
1791
    public List<FofoOrderItem> getByOrderId(int orderId) throws ProfitMandiBusinessException {
1792
        List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(orderId);
1793
        if (!fofoOrderItems.isEmpty()) {
1794
            List<FofoOrderItem> newFofoOrderItems = new ArrayList<>();
1795
            Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = this.toFofoOrderItemIdFofoLineItems(fofoOrderItems);
1796
            Iterator<FofoOrderItem> fofoOrderItemsIterator = fofoOrderItems.iterator();
1797
            while (fofoOrderItemsIterator.hasNext()) {
1798
                FofoOrderItem fofoOrderItem = fofoOrderItemsIterator.next();
1799
                fofoOrderItem.setFofoLineItems(fofoOrderItemIdFofoLineItemsMap.get(fofoOrderItem.getId()));
1800
                newFofoOrderItems.add(fofoOrderItem);
1801
                fofoOrderItemsIterator.remove();
1802
            }
1803
            fofoOrderItems = newFofoOrderItems;
1804
        }
1805
        return fofoOrderItems;
1806
    }
25101 amit.gupta 1807
 
32145 tejbeer 1808
    private Set<Integer> toFofoOrderItemIds(List<FofoOrderItem> fofoOrderItems) {
1809
        Function<FofoOrderItem, Integer> fofoOrderItemToFofoOrderItemIdFunction = new Function<FofoOrderItem, Integer>() {
1810
            @Override
1811
            public Integer apply(FofoOrderItem fofoOrderItem) {
1812
                return fofoOrderItem.getId();
1813
            }
1814
        };
1815
        return fofoOrderItems.stream().map(fofoOrderItemToFofoOrderItemIdFunction).collect(Collectors.toSet());
1816
    }
25101 amit.gupta 1817
 
33247 ranu 1818
    private Map<Integer, Set<FofoLineItem>> toFofoOrderItemIdFofoLineItems(List<FofoOrderItem> fofoOrderItems) throws ProfitMandiBusinessException {
32145 tejbeer 1819
        Set<Integer> fofoOrderItemIds = this.toFofoOrderItemIds(fofoOrderItems);
1820
        List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIds);
1821
        Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = new HashMap<>();
1822
        for (FofoLineItem fofoLineItem : fofoLineItems) {
1823
            if (!fofoOrderItemIdFofoLineItemsMap.containsKey(fofoLineItem.getFofoOrderItemId())) {
1824
                Set<FofoLineItem> fofoLineItems2 = new HashSet<>();
1825
                fofoLineItems2.add(fofoLineItem);
1826
                fofoOrderItemIdFofoLineItemsMap.put(fofoLineItem.getFofoOrderItemId(), fofoLineItems2);
1827
            } else {
1828
                fofoOrderItemIdFofoLineItemsMap.get(fofoLineItem.getFofoOrderItemId()).add(fofoLineItem);
1829
            }
1830
        }
1831
        return fofoOrderItemIdFofoLineItemsMap;
1832
    }
25101 amit.gupta 1833
 
32145 tejbeer 1834
    @Override
1835
    public void updateCustomerDetails(CustomCustomer customCustomer, String invoiceNumber) throws ProfitMandiBusinessException {
1836
        FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
1837
        Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
1838
        customer.setFirstName(customCustomer.getFirstName());
1839
        customer.setLastName(customCustomer.getLastName());
1840
        customer.setMobileNumber(customCustomer.getMobileNumber());
1841
        customer.setEmailId(customCustomer.getEmailId());
1842
        customerRepository.persist(customer);
1843
        CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());
1844
        if (!customerAddress.getState().equalsIgnoreCase(customCustomer.getAddress().getState())) {
1845
            List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
1846
            resetTaxation(fofoOrder.getFofoId(), customerAddress, fofoOrderItems);
1847
        }
1848
        this.setCustomerAddress(customerAddress, customCustomer.getAddress());
1849
        fofoOrder.setCustomerGstNumber(customCustomer.getGstNumber());
1850
    }
23638 amit.gupta 1851
 
32145 tejbeer 1852
    private void resetTaxation(int fofoId, CustomerAddress customerAddress, List<FofoOrderItem> fofoOrderItems) throws ProfitMandiBusinessException {
1853
        int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoId);
23650 amit.gupta 1854
 
32145 tejbeer 1855
        Address retailerAddress = addressRepository.selectById(retailerAddressId);
24275 amit.gupta 1856
 
32145 tejbeer 1857
        Integer stateId = null;
1858
        if (customerAddress.getState().equalsIgnoreCase(retailerAddress.getState())) {
1859
            try {
1860
                stateId = Long.valueOf(stateRepository.selectByName(customerAddress.getState()).getId()).intValue();
1861
            } catch (Exception e) {
1862
                LOGGER.error("Unable to get state rates");
1863
            }
1864
        }
1865
        List<Integer> itemIds = fofoOrderItems.stream().map(x -> x.getItemId()).collect(Collectors.toList());
1866
        final Map<Integer, GstRate> gstRates;
1867
        if (stateId != null) {
1868
            gstRates = stateGstRateRepository.getStateTaxRate(itemIds, stateId);
1869
        } else {
1870
            gstRates = stateGstRateRepository.getIgstTaxRate(itemIds);
1871
        }
1872
        for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
1873
            GstRate rate = gstRates.get(fofoOrderItem.getItemId());
1874
            fofoOrderItem.setCgstRate(rate.getCgstRate());
1875
            fofoOrderItem.setSgstRate(rate.getSgstRate());
1876
            fofoOrderItem.setIgstRate(rate.getIgstRate());
1877
        }
1878
    }
24275 amit.gupta 1879
 
32145 tejbeer 1880
    @Override
1881
    public CustomerCreditNote badReturn(int fofoId, FoiBadReturnRequest foiBadReturnRequest) throws ProfitMandiBusinessException {
1882
        FofoOrderItem foi = fofoOrderItemRepository.selectById(foiBadReturnRequest.getFofoOrderItemId());
1883
        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(foi.getOrderId());
1884
        if (fofoOrder.getFofoId() != fofoId) {
1885
            throw new ProfitMandiBusinessException("Partner Auth", "", "Invalid Order");
1886
        }
1887
        int billedQty = foi.getQuantity() - customerReturnItemRepository.selectAllByOrderItemId(foi.getId()).size();
1888
        if (foiBadReturnRequest.getMarkedBadArr().size() > billedQty) {
1889
            throw new ProfitMandiBusinessException("Cant bad return more than what is billed", "", "Invalid Quantity");
1890
        }
1891
        List<CustomerReturnItem> customerReturnItems = new ArrayList<>();
1892
        for (BadReturnRequest badReturnRequest : foiBadReturnRequest.getMarkedBadArr()) {
1893
            CustomerReturnItem customerReturnItem = new CustomerReturnItem();
1894
            customerReturnItem.setFofoId(fofoId);
1895
            customerReturnItem.setFofoOrderItemId(foiBadReturnRequest.getFofoOrderItemId());
1896
            customerReturnItem.setFofoOrderId(fofoOrder.getId());
1897
            customerReturnItem.setRemarks(badReturnRequest.getRemarks());
1898
            customerReturnItem.setInventoryItemId(badReturnRequest.getInventoryItemId());
1899
            customerReturnItem.setQuantity(1);
1900
            customerReturnItem.setType(ReturnType.BAD);
1901
            // customerReturnItemRepository.persist(customerReturnItem);
1902
            inventoryService.saleReturnInventoryItem(customerReturnItem);
1903
            customerReturnItems.add(customerReturnItem);
1904
        }
1905
        CustomerCreditNote creditNote = generateCreditNote(fofoOrder, customerReturnItems);
1906
        for (CustomerReturnItem customerReturnItem : customerReturnItems) {
1907
            purchaseReturnService.returnInventoryItem(fofoId, false, customerReturnItem.getInventoryItemId(), ReturnType.BAD);
1908
        }
1909
        // This should cancel the order
1910
        fofoOrder.setCancelledTimestamp(LocalDateTime.now());
1911
        this.reverseScheme(fofoOrder);
1912
        return creditNote;
1913
    }
23638 amit.gupta 1914
 
32145 tejbeer 1915
    private CustomerCreditNote generateCreditNote(FofoOrder fofoOrder, List<CustomerReturnItem> customerReturnItems) throws ProfitMandiBusinessException {
24275 amit.gupta 1916
 
32145 tejbeer 1917
        InvoiceNumberGenerationSequence sequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoOrder.getFofoId());
1918
        sequence.setCreditNoteSequence(sequence.getCreditNoteSequence() + 1);
1919
        invoiceNumberGenerationSequenceRepository.persist(sequence);
24275 amit.gupta 1920
 
32145 tejbeer 1921
        String creditNoteNumber = sequence.getPrefix() + "/" + sequence.getCreditNoteSequence();
1922
        CustomerCreditNote creditNote = new CustomerCreditNote();
1923
        creditNote.setCreditNoteNumber(creditNoteNumber);
1924
        creditNote.setFofoId(fofoOrder.getFofoId());
1925
        creditNote.setFofoOrderId(fofoOrder.getId());
1926
        creditNote.setFofoOrderItemId(customerReturnItems.get(0).getFofoOrderItemId());
1927
        creditNote.setSettlementType(SettlementType.UNSETTLED);
1928
        customerCreditNoteRepository.persist(creditNote);
24275 amit.gupta 1929
 
32145 tejbeer 1930
        for (CustomerReturnItem customerReturnItem : customerReturnItems) {
1931
            customerReturnItem.setCreditNoteId(creditNote.getId());
1932
            customerReturnItemRepository.persist(customerReturnItem);
1933
        }
1934
        // this.returnInventoryItems(inventoryItems, debitNote);
23655 amit.gupta 1935
 
32145 tejbeer 1936
        return creditNote;
1937
    }
23655 amit.gupta 1938
 
32145 tejbeer 1939
    @Override
1940
    public CreditNotePdfModel getCreditNotePdfModel(int customerCreditNoteId) throws ProfitMandiBusinessException {
1941
        CustomerCreditNote creditNote = customerCreditNoteRepository.selectById(customerCreditNoteId);
1942
        return getCreditNotePdfModel(creditNote);
1943
    }
24275 amit.gupta 1944
 
32145 tejbeer 1945
    private CreditNotePdfModel getCreditNotePdfModel(CustomerCreditNote creditNote) throws ProfitMandiBusinessException {
1946
        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(creditNote.getFofoOrderId());
1947
        List<CustomerReturnItem> customerReturnItems = customerReturnItemRepository.selectAllByCreditNoteId(creditNote.getId());
33090 amit.gupta 1948
        CustomRetailer customRetailer = retailerService.getFofoRetailer(fofoOrder.getFofoId());
1949
        CustomCustomer customCustomer = getCustomCustomer(fofoOrder, customRetailer.getAddress());
24275 amit.gupta 1950
 
33298 amit.gupta 1951
        List<CustomOrderItem> customerFofoOrderItems = new ArrayList<>();
23655 amit.gupta 1952
 
32145 tejbeer 1953
        FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(creditNote.getFofoOrderItemId());
1954
        float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
1955
        float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
1956
        float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
24275 amit.gupta 1957
 
32145 tejbeer 1958
        CustomOrderItem customFofoOrderItem = new CustomOrderItem();
1959
        customFofoOrderItem.setAmount(customerReturnItems.size() * (taxableSellingPrice - taxableDiscountPrice));
1960
        customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
24275 amit.gupta 1961
 
32145 tejbeer 1962
        if (ItemType.SERIALIZED.equals(itemRepository.selectById(fofoOrderItem.getItemId()).getType())) {
1963
            Set<Integer> inventoryItemIds = customerReturnItems.stream().map(x -> x.getInventoryItemId()).collect(Collectors.toSet());
1964
            List<String> serialNumbers = inventoryItemRepository.selectByIds(inventoryItemIds).stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());
1965
            customFofoOrderItem.setDescription(
1966
                    customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
1967
        }
23638 amit.gupta 1968
 
32145 tejbeer 1969
        customFofoOrderItem.setRate(taxableSellingPrice);
1970
        customFofoOrderItem.setDiscount(taxableDiscountPrice);
1971
        customFofoOrderItem.setQuantity(customerReturnItems.size());
1972
        customFofoOrderItem.setNetAmount(
1973
                (fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * customFofoOrderItem.getQuantity());
29707 tejbeer 1974
 
32145 tejbeer 1975
        float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
1976
        float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
1977
        float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
1978
        LOGGER.info("fofoOrderItem - {}", fofoOrderItem);
1979
        customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
1980
        customFofoOrderItem.setIgstAmount(igstAmount);
1981
        customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
1982
        customFofoOrderItem.setCgstAmount(cgstAmount);
1983
        customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
1984
        customFofoOrderItem.setSgstAmount(sgstAmount);
1985
        customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
1986
        customFofoOrderItem.setOrderId(1);
1987
        customerFofoOrderItems.add(customFofoOrderItem);
29707 tejbeer 1988
 
32145 tejbeer 1989
        InvoicePdfModel pdfModel = new InvoicePdfModel();
1990
        pdfModel.setAuther("NSSPL");
1991
        pdfModel.setCustomer(customCustomer);
1992
        pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
1993
        pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));
1994
        pdfModel.setTitle("Credit Note");
1995
        pdfModel.setRetailer(customRetailer);
1996
        pdfModel.setTotalAmount(customFofoOrderItem.getNetAmount());
1997
        pdfModel.setOrderItems(customerFofoOrderItems);
29707 tejbeer 1998
 
32145 tejbeer 1999
        CreditNotePdfModel creditNotePdfModel = new CreditNotePdfModel();
2000
        creditNotePdfModel.setCreditNoteDate(FormattingUtils.formatDate(creditNote.getCreateTimestamp()));
2001
        creditNotePdfModel.setCreditNoteNumber(creditNote.getCreditNoteNumber());
2002
        creditNotePdfModel.setPdfModel(pdfModel);
2003
        return creditNotePdfModel;
2004
    }
24264 amit.gupta 2005
 
32145 tejbeer 2006
    // This will remove the order and maintain order record and reverse inventory
2007
    // and scheme
2008
    @Override
2009
    public void cancelOrder(List<String> invoiceNumbers) throws ProfitMandiBusinessException {
2010
        for (String invoiceNumber : invoiceNumbers) {
2011
            // Cancel only when not cancelled
2012
            FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
2013
            if (fofoOrder.getCancelledTimestamp() == null) {
2014
                fofoOrder.setCancelledTimestamp(LocalDateTime.now());
2015
                PaymentOptionTransaction paymentTransaction = new PaymentOptionTransaction();
2016
                paymentTransaction.setAmount(-fofoOrder.getTotalAmount());
2017
                paymentTransaction.setFofoId(fofoOrder.getFofoId());
2018
                paymentTransaction.setReferenceId(fofoOrder.getId());
2019
                paymentTransaction.setReferenceType(PaymentOptionReferenceType.ORDER);
2020
                paymentTransaction.setPaymentOptionId(1);
2021
                paymentOptionTransactionRepository.persist(paymentTransaction);
31030 amit.gupta 2022
 
32145 tejbeer 2023
                List<FofoOrderItem> fois = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
2024
                if (fois.size() > 0) {
2025
                    List<InventoryItem> inventoryItems = new ArrayList<>();
2026
                    fois.stream().forEach(x -> {
2027
                        x.getFofoLineItems().stream().forEach(y -> {
2028
                            inventoryService.rollbackInventory(y.getInventoryItemId(), y.getQuantity(), fofoOrder.getFofoId());
2029
                            inventoryItems.add(inventoryItemRepository.selectById(y.getInventoryItemId()));
2030
                        });
2031
                    });
2032
                    // if(invoice)
2033
                    this.reverseScheme(fofoOrder);
2034
                }
2035
                insuranceService.cancelInsurance(fofoOrder);
2036
            }
2037
        }
2038
    }
31030 amit.gupta 2039
 
32145 tejbeer 2040
    @Override
2041
    public void reverseScheme(FofoOrder fofoOrder) throws ProfitMandiBusinessException {
2042
        String reversalReason = "Order Rolledback/Cancelled/Returned for Invoice #" + fofoOrder.getInvoiceNumber();
2043
        List<FofoOrderItem> fois = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
2044
        Set<Integer> inventoryItemIds = fois.stream().flatMap(x -> x.getFofoLineItems().stream().map(y -> y.getInventoryItemId())).collect(Collectors.toSet());
2045
        List<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIds);
2046
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, SchemeService.OUT_SCHEME_TYPES);
2047
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.INVESTMENT));
2048
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.ACTIVATION));
2049
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.SPECIAL_SUPPORT));
31030 amit.gupta 2050
 
32145 tejbeer 2051
    }
24271 amit.gupta 2052
 
32145 tejbeer 2053
    @Override
2054
    public void reverseActivationScheme(List<Integer> inventoryItemIds) throws ProfitMandiBusinessException {
2055
        List<InventoryItem> inventoryItems = inventoryItemRepository.selectAllByIds(inventoryItemIds);
2056
        for (InventoryItem inventoryItem : inventoryItems) {
2057
            List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByInventoryItemId(inventoryItem.getId());
2058
            FofoLineItem fofoLineItem = fofoLineItems.get(0);
2059
            FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(fofoLineItem.getFofoOrderItemId());
2060
            FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(fofoOrderItem.getOrderId());
2061
            String reversalReason = "Scheme rolled back as activation date is invalid for imei " + inventoryItem.getSerialNumber();
2062
            schemeService.reverseSchemes(Arrays.asList(inventoryItem), fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.ACTIVATION));
2063
            schemeService.reverseSchemes(Arrays.asList(inventoryItem), fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.SPECIAL_SUPPORT));
27083 amit.gupta 2064
 
32145 tejbeer 2065
        }
24271 amit.gupta 2066
 
32145 tejbeer 2067
    }
24271 amit.gupta 2068
 
32145 tejbeer 2069
    @Override
2070
    public float getSales(int fofoId, LocalDateTime startDate, LocalDateTime endDate) {
2071
        Float sales = fofoOrderRepository.selectSaleSumGroupByFofoIds(startDate, endDate).get(fofoId);
2072
        return sales == null ? 0f : sales;
2073
    }
24271 amit.gupta 2074
 
32145 tejbeer 2075
    @Override
2076
    public LocalDateTime getMaxSalesDate(int fofoId, LocalDateTime startDate, LocalDateTime endDate) {
2077
        LocalDateTime dateTime = fofoOrderRepository.selectMaxSaleDateGroupByFofoIds(startDate, endDate).get(fofoId);
2078
        return dateTime;
2079
    }
25101 amit.gupta 2080
 
32145 tejbeer 2081
    @Override
2082
    // Only being used internally
2083
    public float getSales(int fofoId, LocalDate onDate) {
2084
        LocalDateTime startTime = LocalDateTime.of(onDate, LocalTime.MIDNIGHT);
2085
        LocalDateTime endTime = LocalDateTime.of(onDate, LocalTime.MIDNIGHT).plusDays(1);
2086
        return this.getSales(fofoId, startTime, endTime);
2087
    }
24917 tejbeer 2088
 
32145 tejbeer 2089
    @Override
2090
    public float getSales(LocalDateTime onDate) {
2091
        // TODO Auto-generated method stub
2092
        return 0;
2093
    }
28166 tejbeer 2094
 
32145 tejbeer 2095
    @Override
2096
    public float getSales(LocalDateTime startDate, LocalDateTime endDate) {
2097
        // TODO Auto-generated method stub
2098
        return 0;
2099
    }
28166 tejbeer 2100
 
32145 tejbeer 2101
    @Override
2102
    public boolean notifyColorChange(int orderId, int itemId) throws ProfitMandiBusinessException {
2103
        Order order = orderRepository.selectById(orderId);
2104
        saholicInventoryService.reservationCountByColor(itemId, order);
28166 tejbeer 2105
 
32145 tejbeer 2106
        order.getLineItem().setItemId(itemId);
2107
        Item item = itemRepository.selectById(itemId);
2108
        order.getLineItem().setColor(item.getColor());
2109
        return true;
2110
    }
28166 tejbeer 2111
 
32145 tejbeer 2112
    @Override
2113
    public FofoOrder getOrderByInventoryItemId(int inventoryItemId) throws Exception {
2114
        List<FofoLineItem> lineItems = fofoLineItemRepository.selectByInventoryItemId(inventoryItemId);
2115
        if (lineItems.size() > 0) {
2116
            FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(lineItems.get(0).getFofoOrderItemId());
2117
            fofoOrderItem.setFofoLineItems(new HashSet<>(lineItems));
2118
            FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(fofoOrderItem.getOrderId());
2119
            fofoOrder.setOrderItem(fofoOrderItem);
2120
            return fofoOrder;
2121
        } else {
2122
            throw new Exception(String.format("Could not find inventoryItemId - %s", inventoryItemId));
2123
        }
2124
    }
28166 tejbeer 2125
 
32145 tejbeer 2126
    @Override
2127
    public Map<Integer, Long> carryBagCreditCount(int fofoId) throws ProfitMandiBusinessException {
28166 tejbeer 2128
 
32145 tejbeer 2129
        FofoStore fs = fofoStoreRepository.selectByRetailerId(fofoId);
2130
        LocalDateTime lastCredit = fs.getBagsLastCredited();
2131
        /*
2132
         * long carryBagCount = 0; List<FofoOrder> fofoOrders =
2133
         * fofoOrderRepository.selectByFofoIdBetweenCreatedTimeStamp(fofoId,
2134
         * lastCredit.atStartOfDay(), LocalDate.now().plusDays(1).atStartOfDay()); for
2135
         * (FofoOrder fo : fofoOrders) { carryBagCount +=
2136
         * fofoOrderItemRepository.selectByOrderId(fo.getId()).stream() .filter(x ->
2137
         * x.getSellingPrice() >= 12000).count();
2138
         *
2139
         * }
2140
         */
28166 tejbeer 2141
 
32145 tejbeer 2142
        Session session = sessionFactory.getCurrentSession();
2143
        CriteriaBuilder cb = session.getCriteriaBuilder();
2144
 
2145
        CriteriaQuery<SimpleEntry> query = cb.createQuery(SimpleEntry.class);
2146
        Root<FofoOrder> fofoOrder = query.from(FofoOrder.class);
2147
        Root<FofoOrderItem> fofoOrderItem = query.from(FofoOrderItem.class);
2148
        Root<TagListing> tagListingRoot = query.from(TagListing.class);
2149
        Root<Item> itemRoot = query.from(Item.class);
2150
 
2151
        Predicate p2 = cb.between(fofoOrder.get(ProfitMandiConstants.CREATE_TIMESTAMP), lastCredit, LocalDate.now().atStartOfDay());
2152
        Predicate p3 = cb.isNull(fofoOrder.get("cancelledTimestamp"));
2153
        Predicate joinPredicate = cb.and(
2154
                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));
2155
        ItemCriteria itemCriteria = new ItemCriteria();
2156
        itemCriteria.setBrands(mongoClient.getMongoBrands(fofoId, null, 3).stream().map(x -> (String) x.get("name")).collect(Collectors.toList()));
2157
        float startValue = 12000;
2158
        itemCriteria.setStartPrice(startValue);
2159
        itemCriteria.setEndPrice(0);
2160
        itemCriteria.setFeaturedPhone(false);
2161
        itemCriteria.setSmartPhone(true);
2162
        itemCriteria.setCatalogIds(new ArrayList<>());
2163
        itemCriteria.setExcludeCatalogIds(new ArrayList<>());
2164
        Predicate itemPredicate = itemRepository.getItemPredicate(itemCriteria, cb, itemRoot, tagListingRoot.get("itemId"), tagListingRoot.get("sellingPrice"));
2165
        Predicate finalPredicate = cb.and(itemPredicate, p2, p3, joinPredicate);
2166
        query = query.multiselect(fofoOrder.get(ProfitMandiConstants.FOFO_ID), cb.count(fofoOrder)).where(finalPredicate).groupBy(fofoOrder.get(ProfitMandiConstants.FOFO_ID));
2167
        List<SimpleEntry> simpleEntries = session.createQuery(query).getResultList();
2168
        Map<Integer, Long> returnMap = new HashMap<>();
2169
 
2170
        for (SimpleEntry simpleEntry : simpleEntries) {
2171
            returnMap.put((Integer) simpleEntry.getKey(), (Long) simpleEntry.getValue());
2172
        }
2173
        return returnMap;
2174
 
2175
    }
32607 ranu 2176
 
2177
    @Override
2178
    public void createMissingScratchOffers() {
2179
        List<FofoOrder> fofoOrders = fofoOrderRepository.selectFromSaleDate(LocalDate.of(2023, 11, 6).atStartOfDay());
2180
        for (FofoOrder fofoOrder : fofoOrders) {
2181
            if (fofoOrder.getCancelledTimestamp() == null) { // Check if cancelled_timestamp is not null
2182
                try {
2183
                    this.createScratchOffer(fofoOrder.getFofoId(), fofoOrder.getInvoiceNumber(), fofoOrder.getCustomerId());
2184
                } catch (Exception e) {
2185
                    LOGGER.error("Error while processing missing scratch offer invoice orderId", fofoOrder.getId());
2186
                }
2187
            }
2188
        }
2189
    }
32724 amit.gupta 2190
 
2191
    @Override
2192
    public boolean refundOrder(int orderId, String refundedBy, String refundReason) throws ProfitMandiBusinessException {
2193
        /*def refund_order(order_id, refunded_by, reason):
2194
        """
2195
        If the order is in RTO_RECEIVED_PRESTINE, DOA_CERT_VALID or DOA_CERT_INVALID state, it does the following:
2196
            1. Creates a refund request for batch processing.
2197
            2. Creates a return order for the warehouse executive to return the shipped material.
2198
            3. Marks the current order as RTO_REFUNDED, DOA_VALID_REFUNDED or DOA_INVALID_REFUNDED final states.
2199
 
2200
        If the order is in SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2201
            1. Creates a refund request for batch processing.
2202
            2. Cancels the reservation of the item in the warehouse.
2203
            3. Marks the current order as the REFUNDED final state.
2204
 
2205
        For all COD orders, if the order is in INIT, SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2206
            1. Cancels the reservation of the item in the warehouse.
2207
            2. Marks the current order as CANCELED.
2208
 
2209
        In all cases, it updates the reason for cancellation or refund and the person who performed the action.
2210
 
2211
        Returns True if it is successful, False otherwise.
2212
 
2213
        Throws an exception if the order with the given id couldn't be found.
2214
 
2215
        Parameters:
2216
         - order_id
2217
         - refunded_by
2218
         - reason
2219
        """
2220
        LOGGER.info("Refunding order id: {}", orderId);
2221
        Order order = orderRepository.selectById(orderId);
2222
 
2223
        if order.cod:
2224
        logging.info("Refunding COD order with status " + str(order.status))
2225
        status_transition = refund_status_transition
2226
        if order.status not in status_transition.keys():
2227
        raise TransactionServiceException(114, "This order can't be refunded")
2228
 
2229
        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]:
2230
        __update_inventory_reservation(order, refund=True)
2231
        order.statusDescription = "Order Cancelled"
2232
            #Shipment Id and Airway Bill No should be none in case of Cancellation
2233
        order.logisticsTransactionId = None
2234
        order.tracking_id = None
2235
        order.airwaybill_no = None
2236
        elif order.status == OrderStatus.BILLED:
2237
        __create_return_order(order)
2238
        order.statusDescription = "Order Cancelled"
2239
        elif order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT]:
2240
        if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2241
        __create_return_order(order)
2242
        order.statusDescription = "RTO Refunded"
2243
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
2244
            #__create_return_order(order)
2245
        order.statusDescription = "Lost in Transit Refunded"
2246
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
2247
        if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2248
        __create_return_order(order)
2249
        __create_refund(order, 0, 'Should be unreachable for now')
2250
        order.statusDescription = "DOA Refunded"
2251
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
2252
        if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2253
        __create_return_order(order)
2254
        __create_refund(order, 0, 'Should be unreachable for now')
2255
        order.statusDescription = "Return Refunded"
2256
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
2257
        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]:
2258
        __update_inventory_reservation(order, refund=True)
2259
        order.statusDescription = "Order Cancelled on customer request"
2260
        elif order.previousStatus == OrderStatus.BILLED:
2261
        __create_return_order(order)
2262
        order.statusDescription = "Order Cancelled on customer request"
2263
        order.received_return_timestamp = datetime.datetime.now()
2264
    else:
2265
        status_transition = {OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,
2266
                OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,
2267
                OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,
2268
                OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,
2269
                OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,
2270
                OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,
2271
                OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,
2272
                OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,
2273
                OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,
2274
                OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,
2275
                OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,
2276
                OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,
2277
                OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2278
                OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2279
                OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2280
                OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2281
                OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2282
                OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2283
                OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2284
                OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST,
2285
                OrderStatus.PAYMENT_FLAGGED : OrderStatus.PAYMENT_FLAGGED_DENIED
2286
                     }
2287
        if order.status not in status_transition.keys():
2288
        raise TransactionServiceException(114, "This order can't be refunded")
2289
 
2290
        if order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT] :
2291
        if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2292
        __create_return_order(order)
2293
        __create_refund(order, order.wallet_amount, 'Order #{0} is RTO refunded'.format(order.id))
2294
        order.statusDescription = "RTO Refunded"
2295
            #Start:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013
2296
        try:
2297
        crmServiceClient = CRMClient().get_client()
2298
        ticket =Ticket()
2299
        activity = Activity()
2300
 
2301
        description = "Creating Ticket for " + order.statusDescription + " Order"
2302
        ticket.creatorId = 1
2303
        ticket.assigneeId = 34
2304
        ticket.category = TicketCategory.RTO_REFUND
2305
        ticket.priority = TicketPriority.MEDIUM
2306
        ticket.status = TicketStatus.OPEN
2307
        ticket.description = description
2308
        ticket.orderId = order.id
2309
 
2310
        activity.creatorId = 1
2311
        activity.ticketAssigneeId = ticket.assigneeId
2312
        activity.type = ActivityType.OTHER
2313
        activity.description = description
2314
        activity.ticketCategory = ticket.category
2315
        activity.ticketDescription = ticket.description
2316
        activity.ticketPriority = ticket.priority
2317
        activity.ticketStatus = ticket.status
2318
 
2319
        ticket.customerId= order.customer_id
2320
        ticket.customerEmailId = order.customer_email
2321
        ticket.customerMobileNumber = order.customer_mobilenumber
2322
        ticket.customerName = order.customer_name
2323
        activity.customerId = ticket.customerId
2324
        activity.customerEmailId = order.customer_email
2325
        activity.customerMobileNumber = order.customer_mobilenumber
2326
        activity.customerName = order.customer_name
2327
 
2328
        crmServiceClient.insertTicket(ticket, activity)
2329
 
2330
        except:
2331
        print "Ticket for RTO Refund is not created."
2332
            #End:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013
2333
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
2334
            #__create_return_order(order)
2335
        __create_refund(order, order.wallet_amount, 'Order #{0} is Lost in Transit'.format(order.id))
2336
        order.statusDescription = "Lost in Transit Refunded"
2337
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
2338
        if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2339
        __create_return_order(order)
2340
        __create_refund(order, 0, 'This should be unreachable')
2341
        order.statusDescription = "DOA Refunded"
2342
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
2343
        if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2344
        __create_return_order(order)
2345
        __create_refund(order, 0, 'This should be unreachable')
2346
        order.statusDescription = "Return Refunded"
2347
        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]:
2348
        __update_inventory_reservation(order, refund=True)
2349
        order.statusDescription = "Order Refunded"
2350
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
2351
        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]:
2352
        __update_inventory_reservation(order, refund=True)
2353
        order.statusDescription = "Order Cancelled on customer request"
2354
        elif order.previousStatus == OrderStatus.BILLED:
2355
        __create_refund(order, order.wallet_amount,  'Order #{0} Cancelled on customer request'.format(order.id))
2356
        order.statusDescription = "Order Cancelled on customer request"
2357
 
2358
        elif order.status == OrderStatus.PAYMENT_FLAGGED:
2359
        __update_inventory_reservation(order, refund=True)
2360
        order.statusDescription = "Order Cancelled due to payment flagged"
2361
 
2362
    # For orders that are cancelled after being billed, we need to scan in the scanned out
2363
    # inventory item and change availability accordingly
2364
        inventoryClient = InventoryClient().get_client()
2365
        warehouse = inventoryClient.getWarehouse(order.warehouse_id)
2366
        if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
2367
        #Now BILLED orders can also be refunded directly with low inventory cancellations
2368
        if order.status in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH]:
2369
        __create_refund(order, order.wallet_amount, reason)
2370
        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]):
2371
        lineitem = order.lineitems[0]
2372
        catalogClient = CatalogClient().get_client()
2373
        item = catalogClient.getItem(lineitem.item_id)
2374
        warehouseClient = WarehouseClient().get_client()
2375
        if warehouse.billingType == BillingType.OURS:
2376
        if ItemType.SERIALIZED == item.type:
2377
        for serial_number in str(lineitem.serial_number).split(','):
2378
        warehouseClient.scanSerializedItemForOrder(serial_number, ScanType.SALE_RET, order.id, order.fulfilmentWarehouseId, 1, order.warehouse_id)
2379
                else:
2380
        warehouseClient.scanForOrder(None, ScanType.SALE_RET, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2381
        if warehouse.billingType == BillingType.OURS_EXTERNAL:
2382
        warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)
2383
        if order.freebieItemId:
2384
        warehouseClient.scanfreebie(order.id, order.freebieItemId, 0, ScanType.SALE_RET)
2385
 
2386
        order.status = status_transition[order.status]
2387
        order.statusDescription = OrderStatus._VALUES_TO_NAMES[order.status]
2388
        order.refund_timestamp = datetime.datetime.now()
2389
        order.refunded_by = refunded_by
2390
        order.refund_reason = reason
2391
    #to re evaluate the shipping charge if any order is being cancelled.
2392
    #_revaluate_shiping(order_id)
2393
        session.commit()
2394
        return True*/
2395
        return true;
2396
    }
2397
 
2398
    @Autowired
2399
    DebitNoteRepository debitNoteRepository;
2400
 
2401
    //initiate refund only if the stock is returned
2402
 
25724 amit.gupta 2403
}