Subversion Repositories SmartDukaan

Rev

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