Subversion Repositories SmartDukaan

Rev

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