Subversion Repositories SmartDukaan

Rev

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