Subversion Repositories SmartDukaan

Rev

Rev 32218 | Rev 32420 | 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
 
32218 tejbeer 3
import java.io.ByteArrayInputStream;
4
import java.io.InputStream;
5
import java.time.LocalDate;
6
import java.time.LocalDateTime;
7
import java.time.LocalTime;
8
import java.util.AbstractMap.SimpleEntry;
9
import java.util.ArrayList;
10
import java.util.Arrays;
11
import java.util.HashMap;
12
import java.util.HashSet;
13
import java.util.Iterator;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.Optional;
17
import java.util.Random;
18
import java.util.Set;
19
import java.util.function.Function;
20
import java.util.stream.Collectors;
21
 
22
import javax.persistence.criteria.CriteriaBuilder;
23
import javax.persistence.criteria.CriteriaQuery;
24
import javax.persistence.criteria.Predicate;
25
import javax.persistence.criteria.Root;
26
 
27
import org.apache.logging.log4j.LogManager;
28
import org.apache.logging.log4j.Logger;
29
import org.hibernate.Session;
30
import org.hibernate.SessionFactory;
31
import org.json.JSONObject;
32
import org.springframework.beans.factory.annotation.Autowired;
33
import org.springframework.beans.factory.annotation.Qualifier;
34
import org.springframework.beans.factory.annotation.Value;
35
import org.springframework.cache.annotation.Cacheable;
36
import org.springframework.core.io.InputStreamResource;
37
import org.springframework.http.HttpHeaders;
38
import org.springframework.http.HttpStatus;
39
import org.springframework.http.ResponseEntity;
40
import org.springframework.stereotype.Component;
41
 
24264 amit.gupta 42
import com.spice.profitmandi.common.enumuration.ItemType;
23202 ashik.ali 43
import com.spice.profitmandi.common.enumuration.SearchType;
22859 ashik.ali 44
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
32218 tejbeer 45
import com.spice.profitmandi.common.model.BadReturnRequest;
46
import com.spice.profitmandi.common.model.CartFofo;
47
import com.spice.profitmandi.common.model.CreateOrderRequest;
48
import com.spice.profitmandi.common.model.CreditNotePdfModel;
49
import com.spice.profitmandi.common.model.CustomAddress;
50
import com.spice.profitmandi.common.model.CustomCustomer;
51
import com.spice.profitmandi.common.model.CustomFofoOrderItem;
52
import com.spice.profitmandi.common.model.CustomInsurancePolicy;
53
import com.spice.profitmandi.common.model.CustomOrderItem;
54
import com.spice.profitmandi.common.model.CustomPaymentOption;
55
import com.spice.profitmandi.common.model.CustomRetailer;
56
import com.spice.profitmandi.common.model.FoiBadReturnRequest;
57
import com.spice.profitmandi.common.model.GstRate;
58
import com.spice.profitmandi.common.model.InsuranceModel;
59
import com.spice.profitmandi.common.model.InvoicePdfModel;
60
import com.spice.profitmandi.common.model.ItemIdQuantityAvailability;
61
import com.spice.profitmandi.common.model.PriceModel;
62
import com.spice.profitmandi.common.model.ProfitMandiConstants;
63
import com.spice.profitmandi.common.model.Quantity;
64
import com.spice.profitmandi.common.model.SerialNumberDetail;
23650 amit.gupta 65
import com.spice.profitmandi.common.util.FormattingUtils;
22859 ashik.ali 66
import com.spice.profitmandi.common.util.StringUtils;
23172 ashik.ali 67
import com.spice.profitmandi.common.util.Utils;
29515 tejbeer 68
import com.spice.profitmandi.common.web.client.RestClient;
22859 ashik.ali 69
import com.spice.profitmandi.dao.entity.catalog.Item;
25103 amit.gupta 70
import com.spice.profitmandi.dao.entity.catalog.TagListing;
32218 tejbeer 71
import com.spice.profitmandi.dao.entity.dtr.InsurancePolicy;
72
import com.spice.profitmandi.dao.entity.dtr.PaymentOptionTransaction;
73
import com.spice.profitmandi.dao.entity.dtr.Retailer;
74
import com.spice.profitmandi.dao.entity.dtr.ScratchOffer;
75
import com.spice.profitmandi.dao.entity.dtr.User;
76
import com.spice.profitmandi.dao.entity.fofo.CurrentInventorySnapshot;
77
import com.spice.profitmandi.dao.entity.fofo.Customer;
78
import com.spice.profitmandi.dao.entity.fofo.CustomerAddress;
79
import com.spice.profitmandi.dao.entity.fofo.CustomerCreditNote;
80
import com.spice.profitmandi.dao.entity.fofo.CustomerReturnItem;
81
import com.spice.profitmandi.dao.entity.fofo.FofoLineItem;
82
import com.spice.profitmandi.dao.entity.fofo.FofoOrder;
83
import com.spice.profitmandi.dao.entity.fofo.FofoOrderItem;
84
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
85
import com.spice.profitmandi.dao.entity.fofo.HygieneData;
86
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
87
import com.spice.profitmandi.dao.entity.fofo.InvoiceNumberGenerationSequence;
88
import com.spice.profitmandi.dao.entity.fofo.LiveDemoSerialNumber;
89
import com.spice.profitmandi.dao.entity.fofo.PendingOrder;
90
import com.spice.profitmandi.dao.entity.fofo.PendingOrderItem;
91
import com.spice.profitmandi.dao.entity.fofo.ScanRecord;
28978 amit.gupta 92
import com.spice.profitmandi.dao.entity.inventory.State;
24917 tejbeer 93
import com.spice.profitmandi.dao.entity.transaction.Order;
22859 ashik.ali 94
import com.spice.profitmandi.dao.entity.user.Address;
95
import com.spice.profitmandi.dao.entity.user.Counter;
96
import com.spice.profitmandi.dao.entity.user.PrivateDealUser;
27516 amit.gupta 97
import com.spice.profitmandi.dao.entity.warehouse.WarehouseInventoryItem;
24264 amit.gupta 98
import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;
23546 ashik.ali 99
import com.spice.profitmandi.dao.enumuration.dtr.PaymentOptionReferenceType;
23650 amit.gupta 100
import com.spice.profitmandi.dao.enumuration.fofo.ReturnType;
22859 ashik.ali 101
import com.spice.profitmandi.dao.enumuration.fofo.ScanType;
23655 amit.gupta 102
import com.spice.profitmandi.dao.enumuration.fofo.SettlementType;
29515 tejbeer 103
import com.spice.profitmandi.dao.enumuration.inventory.ScratchedGift;
28339 tejbeer 104
import com.spice.profitmandi.dao.enumuration.transaction.OrderStatus;
22859 ashik.ali 105
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
26817 amit.gupta 106
import com.spice.profitmandi.dao.repository.catalog.StateGstRateRepository;
24823 amit.gupta 107
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
32218 tejbeer 108
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
109
import com.spice.profitmandi.dao.repository.dtr.InsurancePolicyRepository;
110
import com.spice.profitmandi.dao.repository.dtr.InsuranceProviderRepository;
111
import com.spice.profitmandi.dao.repository.dtr.Mongo;
112
import com.spice.profitmandi.dao.repository.dtr.PaymentOptionTransactionRepository;
113
import com.spice.profitmandi.dao.repository.dtr.PolicyNumberGenerationSequenceRepository;
114
import com.spice.profitmandi.dao.repository.dtr.RetailerRegisteredAddressRepository;
115
import com.spice.profitmandi.dao.repository.dtr.RetailerRepository;
116
import com.spice.profitmandi.dao.repository.dtr.ScratchOfferRepository;
117
import com.spice.profitmandi.dao.repository.dtr.UserAccountRepository;
118
import com.spice.profitmandi.dao.repository.dtr.UserRepository;
119
import com.spice.profitmandi.dao.repository.fofo.CurrentInventorySnapshotRepository;
120
import com.spice.profitmandi.dao.repository.fofo.CustomerAddressRepository;
121
import com.spice.profitmandi.dao.repository.fofo.CustomerCreditNoteRepository;
122
import com.spice.profitmandi.dao.repository.fofo.CustomerRepository;
123
import com.spice.profitmandi.dao.repository.fofo.CustomerReturnItemRepository;
124
import com.spice.profitmandi.dao.repository.fofo.FofoLineItemRepository;
125
import com.spice.profitmandi.dao.repository.fofo.FofoOrderItemRepository;
126
import com.spice.profitmandi.dao.repository.fofo.FofoOrderRepository;
127
import com.spice.profitmandi.dao.repository.fofo.HygieneDataRepository;
128
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
129
import com.spice.profitmandi.dao.repository.fofo.InvoiceNumberGenerationSequenceRepository;
130
import com.spice.profitmandi.dao.repository.fofo.LiveDemoBillingRespository;
131
import com.spice.profitmandi.dao.repository.fofo.PaymentOptionRepository;
132
import com.spice.profitmandi.dao.repository.fofo.PendingOrderItemRepository;
133
import com.spice.profitmandi.dao.repository.fofo.PendingOrderRepository;
134
import com.spice.profitmandi.dao.repository.fofo.PurchaseReturnItemRepository;
135
import com.spice.profitmandi.dao.repository.fofo.ScanRecordRepository;
24854 amit.gupta 136
import com.spice.profitmandi.dao.repository.inventory.StateRepository;
24917 tejbeer 137
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
22859 ashik.ali 138
import com.spice.profitmandi.dao.repository.user.AddressRepository;
139
import com.spice.profitmandi.dao.repository.user.CounterRepository;
140
import com.spice.profitmandi.dao.repository.user.PrivateDealUserRepository;
27516 amit.gupta 141
import com.spice.profitmandi.dao.repository.warehouse.WarehouseInventoryItemRepository;
25724 amit.gupta 142
import com.spice.profitmandi.service.integrations.zest.InsuranceService;
31274 amit.gupta 143
import com.spice.profitmandi.service.integrations.zest.MobileInsurancePlan;
23418 ashik.ali 144
import com.spice.profitmandi.service.inventory.InventoryService;
23655 amit.gupta 145
import com.spice.profitmandi.service.inventory.PurchaseReturnService;
26891 amit.gupta 146
import com.spice.profitmandi.service.inventory.SaholicInventoryService;
28166 tejbeer 147
import com.spice.profitmandi.service.offers.ItemCriteria;
22859 ashik.ali 148
import com.spice.profitmandi.service.pricing.PricingService;
149
import com.spice.profitmandi.service.scheme.SchemeService;
23655 amit.gupta 150
import com.spice.profitmandi.service.user.RetailerService;
23395 amit.gupta 151
import com.spice.profitmandi.service.wallet.WalletService;
22859 ashik.ali 152
 
153
@Component
154
public class OrderServiceImpl implements OrderService {
155
 
32145 tejbeer 156
    private static final Logger LOGGER = LogManager.getLogger(OrderServiceImpl.class);
22859 ashik.ali 157
 
32145 tejbeer 158
    private static Map<String, Integer> serialNumberOrderIdMap = new HashMap<>();
31030 amit.gupta 159
 
32145 tejbeer 160
    static {
161
        serialNumberOrderIdMap.put("862897055749275", 67228);
162
    }
31030 amit.gupta 163
 
32145 tejbeer 164
    @Autowired
165
    @Qualifier("fofoInventoryItemRepository")
166
    private InventoryItemRepository inventoryItemRepository;
27083 amit.gupta 167
 
32145 tejbeer 168
    @Autowired
169
    private StateGstRateRepository stateGstRateRepository;
23650 amit.gupta 170
 
32145 tejbeer 171
    @Autowired
172
    private SaholicInventoryService saholicInventoryService;
27083 amit.gupta 173
 
32145 tejbeer 174
    @Autowired
175
    private LiveDemoBillingRespository liveDemoBillingRespository;
24823 amit.gupta 176
 
32145 tejbeer 177
    @Autowired
178
    private InsuranceService insuranceService;
25724 amit.gupta 179
 
32145 tejbeer 180
    @Autowired
181
    private WalletService walletService;
22859 ashik.ali 182
 
32145 tejbeer 183
    @Autowired
184
    @Qualifier("fofoCurrentInventorySnapshotRepository")
185
    private CurrentInventorySnapshotRepository currentInventorySnapshotRepository;
22859 ashik.ali 186
 
32145 tejbeer 187
    @Autowired
188
    private InvoiceNumberGenerationSequenceRepository invoiceNumberGenerationSequenceRepository;
22859 ashik.ali 189
 
32145 tejbeer 190
    @Autowired
191
    private PurchaseReturnService purchaseReturnService;
23655 amit.gupta 192
 
32145 tejbeer 193
    @Autowired
194
    private RetailerService retailerService;
23655 amit.gupta 195
 
32145 tejbeer 196
    @Autowired
197
    private CustomerRepository customerRepository;
23650 amit.gupta 198
 
32145 tejbeer 199
    @Autowired
200
    private PurchaseReturnItemRepository purchaseReturnItemRepository;
22859 ashik.ali 201
 
32145 tejbeer 202
    @Autowired
203
    private AddressRepository addressRepository;
22859 ashik.ali 204
 
32145 tejbeer 205
    @Autowired
206
    private FofoLineItemRepository fofoLineItemRepository;
22859 ashik.ali 207
 
32145 tejbeer 208
    @Autowired
209
    private WarehouseInventoryItemRepository warehouseInventoryItemRepository;
27516 amit.gupta 210
 
32145 tejbeer 211
    @Autowired
212
    private FofoOrderItemRepository fofoOrderItemRepository;
23650 amit.gupta 213
 
32145 tejbeer 214
    @Autowired
215
    private PaymentOptionRepository paymentOptionRepository;
22859 ashik.ali 216
 
32145 tejbeer 217
    @Autowired
218
    private CustomerReturnItemRepository customerReturnItemRepository;
23650 amit.gupta 219
 
32145 tejbeer 220
    @Autowired
221
    @Qualifier("fofoScanRecordRepository")
222
    private ScanRecordRepository scanRecordRepository;
22859 ashik.ali 223
 
32145 tejbeer 224
    @Autowired
225
    private FofoOrderRepository fofoOrderRepository;
22859 ashik.ali 226
 
32145 tejbeer 227
    @Autowired
228
    private RetailerRepository retailerRepository;
22859 ashik.ali 229
 
32145 tejbeer 230
    @Autowired
231
    private UserRepository userRepository;
22859 ashik.ali 232
 
32145 tejbeer 233
    @Autowired
234
    private UserAccountRepository userAccountRepository;
22859 ashik.ali 235
 
32145 tejbeer 236
    @Autowired
237
    private RetailerRegisteredAddressRepository retailerRegisteredAddressRepository;
22859 ashik.ali 238
 
32145 tejbeer 239
    @Autowired
240
    private CustomerAddressRepository customerAddressRepository;
22859 ashik.ali 241
 
32145 tejbeer 242
    @Autowired
243
    @Qualifier("catalogItemRepository")
244
    private ItemRepository itemRepository;
23650 amit.gupta 245
 
32145 tejbeer 246
    @Autowired
247
    private InsuranceProviderRepository insuranceProviderRepository;
23650 amit.gupta 248
 
32145 tejbeer 249
    @Autowired
250
    private InsurancePolicyRepository insurancePolicyRepository;
24917 tejbeer 251
 
32145 tejbeer 252
    @Autowired
253
    private StateRepository stateRepository;
23650 amit.gupta 254
 
32145 tejbeer 255
    @Autowired
256
    private PolicyNumberGenerationSequenceRepository policyNumberGenerationSequenceRepository;
23650 amit.gupta 257
 
32145 tejbeer 258
    @Autowired
259
    private PricingService pricingService;
23650 amit.gupta 260
 
32145 tejbeer 261
    @Autowired
262
    private PrivateDealUserRepository privateDealUserRepository;
23650 amit.gupta 263
 
32145 tejbeer 264
    @Autowired
265
    private TagListingRepository tagListingRepository;
24823 amit.gupta 266
 
32145 tejbeer 267
    @Autowired
268
    private CounterRepository counterRepository;
23650 amit.gupta 269
 
32145 tejbeer 270
    @Autowired
271
    private FofoStoreRepository fofoStoreRepository;
23650 amit.gupta 272
 
32145 tejbeer 273
    @Autowired
274
    private PaymentOptionTransactionRepository paymentOptionTransactionRepository;
23650 amit.gupta 275
 
32145 tejbeer 276
    @Autowired
277
    private SchemeService schemeService;
23650 amit.gupta 278
 
32145 tejbeer 279
    private static final List<Integer> orderIdsConsumed = new ArrayList<>();
28166 tejbeer 280
 
32145 tejbeer 281
    @Autowired
282
    @Qualifier("fofoInventoryService")
283
    private InventoryService inventoryService;
23650 amit.gupta 284
 
32145 tejbeer 285
    @Autowired
286
    private CustomerCreditNoteRepository customerCreditNoteRepository;
23650 amit.gupta 287
 
32145 tejbeer 288
    @Autowired
289
    private OrderRepository orderRepository;
24917 tejbeer 290
 
32145 tejbeer 291
    @Autowired
292
    private HygieneDataRepository hygieneDataRepository;
25640 tejbeer 293
 
32145 tejbeer 294
    @Autowired
295
    private SessionFactory sessionFactory;
28166 tejbeer 296
 
32145 tejbeer 297
    @Autowired
298
    private Mongo mongoClient;
28964 tejbeer 299
 
32145 tejbeer 300
    @Autowired
301
    private PendingOrderRepository pendingOrderRepository;
28964 tejbeer 302
 
32145 tejbeer 303
    @Autowired
304
    private PendingOrderItemRepository pendingOrderItemRepository;
28166 tejbeer 305
 
32145 tejbeer 306
    @Autowired
307
    private ScratchOfferRepository scratchOfferRepository;
29515 tejbeer 308
 
32145 tejbeer 309
    @Autowired
310
    RestClient restClient;
29515 tejbeer 311
 
32145 tejbeer 312
    @Value("${prod}")
313
    private boolean prodEnv;
29515 tejbeer 314
 
32145 tejbeer 315
    private static final String SMS_GATEWAY = "http://api.pinnacle.in/index.php/sms/send";
316
    private static final String SENDER = "SMTDKN";
29515 tejbeer 317
 
32145 tejbeer 318
    public static final String APP_DOWNLOAD_BILLING_TEMPLATE_ID = "1507163542403945677";
29515 tejbeer 319
 
32145 tejbeer 320
    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 321
 
32145 tejbeer 322
    @Override
323
    public int createOrder(CreateOrderRequest createOrderRequest, int fofoId, boolean accessoriesDeals) throws ProfitMandiBusinessException {
324
        LOGGER.info("fofoId -- {} Order Request -- {}", fofoId, createOrderRequest);
325
        CustomCustomer customCustomer = createOrderRequest.getCustomer();
326
        Customer customer = customerRepository.selectById(customCustomer.getCustomerId());
22872 ashik.ali 327
 
32145 tejbeer 328
        if (!StringUtils.isValidGstNumber(customCustomer.getGstNumber())) {
329
            LOGGER.error("invalid customer gstNumber {} ", customCustomer.getGstNumber());
330
            throw new ProfitMandiBusinessException(ProfitMandiConstants.CUSTOMER_GST_NUMBER, customCustomer.getGstNumber(), "VE_1072");
331
        }
23650 amit.gupta 332
 
32145 tejbeer 333
        Map<Integer, Integer> itemIdQuantity = new HashMap<>(); // this is for error
334
        Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap = new HashMap<>();
335
        Map<Integer, Float> lineItemPrice = new HashMap<>(); // this is for pricing error
23650 amit.gupta 336
 
32145 tejbeer 337
        float totalAmount = 0;
338
        boolean noGST = false;
339
        for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
340
            // itemIds.add(customFofoOrderItem.getItemId());
341
            Set<String> serialNumbers = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());
342
            if (!serialNumbers.isEmpty() && customFofoOrderItem.getQuantity() != serialNumbers.size()) {
343
                itemIdQuantity.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
344
            }
345
            if (!(customFofoOrderItem.getSellingPrice() > 0)) {
346
                lineItemPrice.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getSellingPrice());
347
            } else {
348
                totalAmount = totalAmount + customFofoOrderItem.getSellingPrice() * customFofoOrderItem.getQuantity();
349
                for (SerialNumberDetail serialNumberDetail : customFofoOrderItem.getSerialNumberDetails()) {
350
                    if (serialNumberDetail.getAmount() > 0) {
351
                        totalAmount = totalAmount + serialNumberDetail.getAmount();
352
                    }
353
                }
354
            }
23650 amit.gupta 355
 
32145 tejbeer 356
            itemIdCustomFofoOrderItemMap.put(customFofoOrderItem.getItemId(), customFofoOrderItem);
357
        }
358
        if (!itemIdQuantity.isEmpty()) {
359
            // if item quantity does not match with given serialnumbers size
360
            LOGGER.error("itemId's quantity should be equal to given serialnumber size {} ", itemIdQuantity);
361
            throw new ProfitMandiBusinessException("itemIdQuantity", itemIdQuantity, "FFORDR_1001");
362
            // return "error";
363
        }
23650 amit.gupta 364
 
32145 tejbeer 365
        this.validatePaymentOptionsAndTotalAmount(createOrderRequest.getPaymentOptions(), totalAmount);
23650 amit.gupta 366
 
32145 tejbeer 367
        if (!lineItemPrice.isEmpty()) {
368
            // given fofo line item price must be greater than zero
369
            LOGGER.error("requested itemId's selling price must greater than 0");
370
            throw new ProfitMandiBusinessException(ProfitMandiConstants.PRICE, lineItemPrice, "FFORDR_1002");
371
        }
22859 ashik.ali 372
 
32145 tejbeer 373
        List<CurrentInventorySnapshot> currentInventorySnapshots = currentInventorySnapshotRepository.selectByFofoItemIds(fofoId, itemIdCustomFofoOrderItemMap.keySet());
23650 amit.gupta 374
 
32145 tejbeer 375
        this.validateCurrentInventorySnapshotQuantities(currentInventorySnapshots, itemIdCustomFofoOrderItemMap);
22859 ashik.ali 376
 
32145 tejbeer 377
        List<Item> items = itemRepository.selectByIds(itemIdCustomFofoOrderItemMap.keySet());
378
        if (items.size() != itemIdCustomFofoOrderItemMap.keySet().size()) {
379
            LOGGER.error("Requested ItemIds not found in catalog");
380
            // invalid itemIds
381
            throw new ProfitMandiBusinessException("invalidItemIds", itemIdCustomFofoOrderItemMap.keySet(), "FFORDR_1003");
382
        }
23650 amit.gupta 383
 
32145 tejbeer 384
        Map<Integer, Item> itemMap = this.toItemMap(items);
23650 amit.gupta 385
 
32145 tejbeer 386
        Set<Integer> nonSerializedItemIds = new HashSet<>();
387
        Set<String> serialNumbers = new HashSet<>();
388
        List<InsuranceModel> insuredModels = new ArrayList<>();
389
        for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
390
            Item item = itemMap.get(customFofoOrderItem.getItemId());
391
            noGST = item.getHsnCode().equals("NOGST");
392
            if (item.getType().equals(ItemType.SERIALIZED)) {
393
                for (SerialNumberDetail serialNumberDetail : customFofoOrderItem.getSerialNumberDetails()) {
394
                    serialNumbers.add(serialNumberDetail.getSerialNumber());
395
                    if (serialNumberDetail.getAmount() > 0) {
396
                        if (customer.getEmailId() == null || customer.getEmailId().equals("")) {
397
                            throw new ProfitMandiBusinessException("Email Id is required for insurance", "Email Id is required for insurance", "Email Id is required for insurance");
398
                        }
399
                        InsuranceModel im = new InsuranceModel();
400
                        im.setBrand(item.getBrand());
401
                        im.setColor(item.getColor());
402
                        im.setModelName(item.getModelName() + item.getModelNumber());
403
                        im.setInsuranceAmount(serialNumberDetail.getAmount());
404
                        im.setDeviceSellingPrice(customFofoOrderItem.getSellingPrice());
405
                        im.setInsuranceId(serialNumberDetail.getInsurance());
406
                        im.setSerialNumber(serialNumberDetail.getSerialNumber());
407
                        im.setMemory(serialNumberDetail.getMemory());
408
                        im.setRam(serialNumberDetail.getRam());
409
                        im.setMfgDate(serialNumberDetail.getMfgDate());
410
                        insuredModels.add(im);
411
                        // Check for free insurance code
412
                        try {
413
                            Map<String, List<MobileInsurancePlan>> mobileInsurancePlanMap = insuranceService.getAllPlans(item.getId(), im.getDeviceSellingPrice());
414
                            MobileInsurancePlan mobileInsurancePlan = mobileInsurancePlanMap.entrySet().stream().flatMap(x -> x.getValue().stream()).filter(x -> x.getProductId().equals(serialNumberDetail.getInsurance())).findFirst().get();
415
                            LOGGER.info("OneAssist Plan - {}", mobileInsurancePlanMap);
416
                            LOGGER.info("SerialNumber Detqail InsuranceId - {}", serialNumberDetail.getInsurance());
417
                            LOGGER.info("product description - {}", mobileInsurancePlan);
418
                            if (mobileInsurancePlan.getPlanName().equals("OneAssist Damage Protection Plan")) {
419
                                MobileInsurancePlan freePlan = mobileInsurancePlanMap.get("Prolong Extendended Warranty(SmartDukaan Special Price)").get(0);
420
                                InsuranceModel imFree = new InsuranceModel();
421
                                imFree.setBrand(item.getBrand());
422
                                imFree.setColor(item.getColor());
423
                                imFree.setModelName(item.getModelName() + item.getModelNumber());
424
                                imFree.setInsuranceAmount(0);
425
                                imFree.setDeviceSellingPrice(customFofoOrderItem.getSellingPrice());
426
                                imFree.setInsuranceId(freePlan.getProductId());
427
                                imFree.setSerialNumber(serialNumberDetail.getSerialNumber());
428
                                imFree.setMemory(serialNumberDetail.getMemory());
429
                                imFree.setRam(serialNumberDetail.getRam());
430
                                imFree.setMfgDate(serialNumberDetail.getMfgDate());
431
                                insuredModels.add(imFree);
432
                            }
433
                        } catch (Exception e) {
434
                            LOGGER.error("Exception - {}", e);
435
                            throw new ProfitMandiBusinessException("problem fetching plans", "problem fetching plans", "problem fetching plans");
436
                        }
437
                    }
31274 amit.gupta 438
 
32145 tejbeer 439
                }
440
            } else {
441
                nonSerializedItemIds.add(customFofoOrderItem.getItemId());
442
            }
443
        }
23650 amit.gupta 444
 
32145 tejbeer 445
        Map<Integer, Set<InventoryItem>> serializedInventoryItemMap = new HashMap<>();
446
        Map<Integer, Set<InventoryItem>> nonSerializedInventoryItemMap = new HashMap<>();
447
        // Map<String, Float> serialNumberItemPrice = new HashMap<>();
23650 amit.gupta 448
 
32145 tejbeer 449
        if (!serialNumbers.isEmpty()) {
450
            List<InventoryItem> serializedInventoryItems = inventoryItemRepository.selectByFofoIdSerialNumbers(fofoId, serialNumbers, false);
451
            LOGGER.info("serializedInventoryItems {}", serializedInventoryItems);
452
            for (InventoryItem inventoryItem : serializedInventoryItems) {
453
                if (inventoryItem.getGoodQuantity() == 1) {
454
                    if (serializedInventoryItemMap.containsKey(inventoryItem.getItemId())) {
455
                        serializedInventoryItemMap.get(inventoryItem.getItemId()).add(inventoryItem);
456
                    } else {
457
                        Set<InventoryItem> itemIdInventoryItems = new HashSet<>();
458
                        itemIdInventoryItems.add(inventoryItem);
459
                        serializedInventoryItemMap.put(inventoryItem.getItemId(), itemIdInventoryItems);
460
                    }
461
                }
462
            }
463
        }
23418 ashik.ali 464
 
32145 tejbeer 465
        if (!nonSerializedItemIds.isEmpty()) {
466
            List<InventoryItem> nonSerializedInventoryItems = inventoryItemRepository.selectByFofoIdItemIds(fofoId, nonSerializedItemIds);
467
            LOGGER.info("nonSerializedInventoryItems {}", nonSerializedInventoryItems);
468
            for (InventoryItem it : nonSerializedInventoryItems) {
469
                if (it.getGoodQuantity() > 0) {
470
                    if (nonSerializedInventoryItemMap.containsKey(it.getItemId())) {
471
                        nonSerializedInventoryItemMap.get(it.getItemId()).add(it);
472
                    } else {
473
                        Set<InventoryItem> tmp = new HashSet<>();
474
                        tmp.add(it);
475
                        nonSerializedInventoryItemMap.put(it.getItemId(), tmp);
476
                    }
477
                }
478
            }
479
        }
23650 amit.gupta 480
 
32145 tejbeer 481
        this.validateItemsSerializedNonSerialized(items, itemIdCustomFofoOrderItemMap);
22859 ashik.ali 482
 
32145 tejbeer 483
        Map<Integer, Set<InventoryItem>> inventoryItemsToBill = new HashMap<>();
484
        Map<Integer, Integer> inventoryItemIdQuantityUsed = new HashMap<>(); // to keep track of inventoryitem quanity
485
        // used for scan records insertion
22859 ashik.ali 486
 
32145 tejbeer 487
        LOGGER.info("itemMap keys {}", itemMap.keySet());
488
        // Lets reduce quantity and decide what inventory items to use.
489
        for (Item item : items) {
490
            if (item.getType().equals(ItemType.SERIALIZED)) {
491
                // TODO:handle null
492
                if (serializedInventoryItemMap.get(item.getId()) == null || itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().size() != serializedInventoryItemMap.get(item.getId()).size()) {
24440 amit.gupta 493
 
32145 tejbeer 494
                    List<String> invalidSerialNumbers = itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());
495
                    throw new ProfitMandiBusinessException("invalidSerialNumbers", invalidSerialNumbers, "FFORDR_1004");
496
                }
497
                List<String> serialNumberList = liveDemoBillingRespository.selectAllSerialNumber();
24823 amit.gupta 498
 
32145 tejbeer 499
                Set<InventoryItem> inventoryItemsSerializedserialized = serializedInventoryItemMap.get(item.getId());
500
                for (InventoryItem inventoryItem : inventoryItemsSerializedserialized) {
501
                    inventoryItem.setGoodQuantity(0);
502
                    inventoryItemIdQuantityUsed.put(inventoryItem.getId(), 1);
503
                    if (serialNumberList.contains(inventoryItem.getSerialNumber())) {
504
                        LiveDemoSerialNumber liveDemoSerialNumber = liveDemoBillingRespository.selectBySerialNumber(inventoryItem.getSerialNumber());
505
                        liveDemoBillingRespository.delete(liveDemoSerialNumber);
506
                    }
507
                }
508
                inventoryItemsToBill.put(item.getId(), inventoryItemsSerializedserialized);
509
            } else {
510
                Set<InventoryItem> inventoryItemsNonSerialized = nonSerializedInventoryItemMap.get(item.getId());
511
                int quantityToBill = itemIdCustomFofoOrderItemMap.get(item.getId()).getQuantity();
512
                int totalLeft = quantityToBill;
513
                Set<InventoryItem> inventoryItemsNonSerializedUsed = new HashSet<>();
514
                if (inventoryItemsNonSerialized != null) {
515
                    for (InventoryItem inventoryItem : inventoryItemsNonSerialized) {
516
                        if (totalLeft > 0) {
517
                            int toUse = Math.min(totalLeft, inventoryItem.getGoodQuantity());
518
                            inventoryItemIdQuantityUsed.put(inventoryItem.getId(), toUse);
519
                            inventoryItem.setGoodQuantity(inventoryItem.getGoodQuantity() - toUse);
520
                            totalLeft = totalLeft - toUse;
521
                            inventoryItemsNonSerializedUsed.add(inventoryItem);
522
                        }
523
                    }
524
                }
23650 amit.gupta 525
 
32145 tejbeer 526
                if (totalLeft > 0) {
527
                    // not enough quanity for non-serialized
528
                    LOGGER.error("not enough quanity for non-serialized");
529
                    throw new ProfitMandiBusinessException("notEnoughQuantityForNonSerialized", totalLeft, "FFORDR_1005");
530
                }
531
                inventoryItemsToBill.put(item.getId(), inventoryItemsNonSerializedUsed);
532
            }
533
        }
23650 amit.gupta 534
 
32145 tejbeer 535
        Map<Integer, PriceModel> itemIdMopPriceMap = pricingService.getPurchasePriceMopPriceNotFound(itemIdCustomFofoOrderItemMap.keySet(), fofoId);
536
        LOGGER.info("itemIdMopMap {}", itemIdMopPriceMap);
537
        if (accessoriesDeals) {
538
            this.validateDpPrice(itemIdMopPriceMap, itemIdCustomFofoOrderItemMap);
539
        } else {
540
            this.validateMopPrice(itemIdMopPriceMap, itemIdCustomFofoOrderItemMap);
541
        }
23650 amit.gupta 542
 
32145 tejbeer 543
        String fofoStoreCode = this.getFofoStoreCode(fofoId);
544
        String documentNumber = null;
545
        if (noGST) {
546
            documentNumber = this.getSecurityDepositNumber(fofoId, fofoStoreCode);
24275 amit.gupta 547
 
32145 tejbeer 548
        } else {
549
            documentNumber = this.getInvoiceNumber(fofoId, fofoStoreCode);
550
        }
22859 ashik.ali 551
 
32145 tejbeer 552
        CustomerAddress customerAddress = customer.getCustomerAddress().stream().filter(x -> x.getId() == customCustomer.getCustomerAddressId()).findFirst().get();
23650 amit.gupta 553
 
32145 tejbeer 554
        FofoOrder fofoOrder = this.createAndGetFofoOrder(customer.getId(), customCustomer.getGstNumber(), fofoId, documentNumber, totalAmount, customerAddress.getId());
23650 amit.gupta 555
 
32145 tejbeer 556
        this.createPaymentOptions(fofoOrder, createOrderRequest.getPaymentOptions());
23650 amit.gupta 557
 
32145 tejbeer 558
        int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoId);
23650 amit.gupta 559
 
32145 tejbeer 560
        Address retailerAddress = addressRepository.selectById(retailerAddressId);
23650 amit.gupta 561
 
32145 tejbeer 562
        Integer stateId = null;
563
        if (customerAddress.getState().equals(retailerAddress.getState())) {
564
            try {
565
                State state = stateRepository.selectByName(customerAddress.getState());
566
                stateId = Long.valueOf(state.getId()).intValue();
567
            } catch (Exception e) {
568
                LOGGER.error("Unable to get state rates");
569
            }
570
        }
23650 amit.gupta 571
 
32145 tejbeer 572
        for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
573
            FofoOrderItem fofoOrderItem = this.createAndGetFofoOrderItem(customFofoOrderItem, fofoOrder.getId(), itemMap, inventoryItemsToBill.get(customFofoOrderItem.getItemId()), stateId);
23650 amit.gupta 574
 
32145 tejbeer 575
            Set<InventoryItem> inventoryItems = inventoryItemsToBill.get(customFofoOrderItem.getItemId());
23650 amit.gupta 576
 
32145 tejbeer 577
            this.createFofoLineItem(fofoOrderItem.getId(), inventoryItems, inventoryItemIdQuantityUsed);
23650 amit.gupta 578
 
32145 tejbeer 579
            this.updateCurrentInventorySnapshot(currentInventorySnapshots, fofoId, customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
23650 amit.gupta 580
 
32145 tejbeer 581
            this.updateInventoryItemsAndScanRecord(inventoryItems, fofoId, inventoryItemIdQuantityUsed, fofoOrder.getId());
582
        }
23650 amit.gupta 583
 
32145 tejbeer 584
        List<FofoOrderItem> fofoItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
25647 tejbeer 585
 
32145 tejbeer 586
        boolean smartPhone = false;
587
        for (FofoOrderItem fofoItem : fofoItems) {
588
            Item orderItem = itemRepository.selectById(fofoItem.getItemId());
589
            if (orderItem.isSmartPhone()) {
590
                smartPhone = true;
591
            }
31172 tejbeer 592
 
32145 tejbeer 593
        }
31172 tejbeer 594
 
32145 tejbeer 595
        if (smartPhone) {
596
            this.createAndGetHygieneData(fofoOrder.getId(), fofoOrder.getFofoId());
597
        }
598
        // insurance calculation is insurance flag is enabled
599
        //
600
        if (insuredModels.size() > 0) {
601
            LOGGER.info("Processing insurane for serialNumbers");
602
            LOGGER.info("InsuranceModels {}", insuredModels);
603
            LocalDate customerDateOfBirth = LocalDate.from(createOrderRequest.getCustomer().getDateOfBirth());
604
            fofoOrder.setDateOfBirth(customerDateOfBirth);
605
            for (InsuranceModel insuranceModel : insuredModels) {
606
                LOGGER.info("Creating insurance for {}", insuranceModel.getInsuranceId());
607
                insuranceService.createInsurance(fofoOrder, insuranceModel);
608
            }
609
        }
28339 tejbeer 610
 
32145 tejbeer 611
        schemeService.processSchemeOut(fofoOrder.getId(), fofoId);
31993 amit.gupta 612
 
32145 tejbeer 613
        if (createOrderRequest.getPoId() != 0) {
614
            PendingOrder po = pendingOrderRepository.selectById(createOrderRequest.getPoId());
615
            po.setBilledAmount(po.getBilledAmount() + totalAmount);
616
            PendingOrderItem poi = pendingOrderItemRepository.selectById(createOrderRequest.getPoItemId());
617
            poi.setStatus(OrderStatus.BILLED);
618
            poi.setBilledTimestamp(LocalDateTime.now());
619
        }
29515 tejbeer 620
 
32218 tejbeer 621
        LocalDate startDate = LocalDate.of(2023, 07, 22);
622
        LocalDate endDate = LocalDate.of(2023, 07, 23);
29515 tejbeer 623
 
32218 tejbeer 624
 
32219 tejbeer 625
        if (smartPhone && fofoId == 175139406) {
32218 tejbeer 626
 
32145 tejbeer 627
            if (LocalDateTime.now().isAfter(startDate.atStartOfDay()) && LocalDateTime.now().isBefore(endDate.atStartOfDay())) {
29515 tejbeer 628
 
32145 tejbeer 629
                try {
630
                    this.sendAppDownloadBillingOffer(customer.getMobileNumber());
631
                } catch (Exception e) {
632
                    // TODO Auto-generated catch block
633
                    e.printStackTrace();
634
                }
32218 tejbeer 635
 
636
                this.createScratchOffer(fofoId, fofoOrder.getInvoiceNumber(), fofoOrder.getCustomerId());
32145 tejbeer 637
            }
638
        }
639
        return fofoOrder.getId();
640
    }
23650 amit.gupta 641
 
32145 tejbeer 642
    public void sendAppDownloadBillingOffer(String mobileNumber) throws Exception {
643
        // In case of Cant receive SMS?
644
        // String mailMessage = java.text.MessageFormat.format(text, otp.getOtp());
645
        String sdurl = "http://surl.li/anhfn";
646
        try {
647
            if (prodEnv) {
648
                this.sendSms(APP_DOWNLOAD_BILLING_TEMPLATE_ID, String.format(APP_DOWNLOAD_BILLING_OFFER, sdurl), mobileNumber);
649
            }
650
        } catch (Exception e) {
651
            e.printStackTrace();
652
        }
29515 tejbeer 653
 
32145 tejbeer 654
    }
29515 tejbeer 655
 
32145 tejbeer 656
    public void sendSms(String dltTemplateId, String message, String mobileNumber) throws Exception {
657
        Map<String, String> map = new HashMap<>();
29515 tejbeer 658
 
32145 tejbeer 659
        map.put("sender", SENDER);
660
        map.put("messagetype", "TXT");
661
        map.put("apikey", "b866f7-c6c483-682ff5-054420-ad9e2c");
29515 tejbeer 662
 
32145 tejbeer 663
        map.put("numbers", "91" + mobileNumber);
664
        LOGGER.info("Message {}", message);
665
        // OTP Message Template
666
        map.put("message", message);
667
        map.put("dlttempid", dltTemplateId);
29515 tejbeer 668
 
32145 tejbeer 669
        String response = restClient.post(SMS_GATEWAY, map, new HashMap<>());
670
        LOGGER.info(response);
29515 tejbeer 671
 
32145 tejbeer 672
    }
29515 tejbeer 673
 
674
 
32218 tejbeer 675
    private void createScratchOffer(int fofoId, String invoiceNumber, int customerId) {
29515 tejbeer 676
 
32218 tejbeer 677
        Map<Integer, ScratchedGift> giftSeries = new HashMap<>();
678
        giftSeries.put(1, ScratchedGift.MINI_CHOPPER);
679
        giftSeries.put(2, ScratchedGift.FRUIT_JUICER);
680
        giftSeries.put(3, ScratchedGift.STEAM_IRON);
681
 
682
        LocalDate startDate = LocalDate.of(2023, 07, 22);
683
        LocalDate endDate = LocalDate.of(2023, 07, 23);
684
 
685
 
686
        List<FofoOrder> fofoOrders = fofoOrderRepository.selectByFofoIdBetweenCreatedTimeStamp(fofoId, startDate.atStartOfDay(), endDate.atStartOfDay());
687
        ScratchedGift gift = ScratchedGift.BLNT;
688
 
689
        Random random = new Random();
690
        int rand = 0;
691
 
692
        LOGGER.info("Processing insurane for serialNumbers");
693
 
694
        while (true) {
695
            rand = random.nextInt(4);
696
            if (rand != 0) break;
697
        }
698
 
699
        LOGGER.info("rand {}", rand);
700
 
701
        if (fofoOrders.isEmpty()) {
702
 
703
            gift = giftSeries.get(rand);
704
 
705
            LOGGER.info("gift11 {}", gift);
706
 
707
        } else {
708
 
709
            List<String> invoiceNumbers = fofoOrders.stream().filter(x -> x.getCancelledTimestamp() == null).map(x -> x.getInvoiceNumber()).collect(Collectors.toList());
710
 
711
 
712
            List<ScratchOffer> scratchOffers = scratchOfferRepository.selectByInvoiceNumbers(invoiceNumbers);
713
 
714
 
715
            if (scratchOffers.isEmpty()) {
716
 
717
                gift = giftSeries.get(rand);
718
                LOGGER.info("gift3 {}", gift);
719
 
720
 
721
            } else {
722
 
723
                List<ScratchOffer> bigGifts = scratchOffers.stream().filter(x -> !x.getOfferName().equals(ScratchedGift.BLNT) && !x.getOfferName().equals(ScratchedGift.EW)).collect(Collectors.toList());
724
                LOGGER.info("bigGifts {}", bigGifts);
725
 
726
                if (bigGifts.size() <= 10) {
727
                    List<Integer> scratchCustomerIds = scratchOffers.stream().map(x -> x.getCustomerId()).collect(Collectors.toList());
728
 
729
                    if (scratchCustomerIds.contains(customerId)) {
730
 
731
 
732
                        gift = ScratchedGift.BLNT;
733
 
734
                        LOGGER.info("gift2 {}", gift);
735
 
736
                    } else {
737
 
738
                        int miniChopper = (int) bigGifts.stream().filter(x -> x.getOfferName().equals(ScratchedGift.MINI_CHOPPER)).count();
739
                        int fruitJuicer = (int) bigGifts.stream().filter(x -> x.getOfferName().equals(ScratchedGift.FRUIT_JUICER)).count();
740
                        int streanIron = (int) bigGifts.stream().filter(x -> x.getOfferName().equals(ScratchedGift.STEAM_IRON)).count();
741
                        LOGGER.info("miniChopper {}", miniChopper);
742
 
743
                        LOGGER.info("fruitJuicer {}", fruitJuicer);
744
 
745
 
746
                        LOGGER.info("streanIron {}", streanIron);
747
 
748
 
749
                        if (rand == 1) {
750
                            if (miniChopper < 4) {
751
                                LOGGER.info("miniChopper {}", miniChopper);
752
 
753
 
754
                                gift = giftSeries.get(rand);
755
                            }
756
                        }
757
 
758
                        if (rand == 2) {
759
                            if (fruitJuicer < 3) {
760
 
761
                                LOGGER.info("fruitJuicer {}", fruitJuicer);
762
 
763
                                gift = giftSeries.get(rand);
764
                            }
765
                        }
766
 
767
                        if (rand == 3) {
768
                            if (streanIron < 3) {
769
 
770
                                LOGGER.info("streanIron {}", streanIron);
771
 
772
 
773
                                gift = giftSeries.get(rand);
774
 
775
                            }
776
                        }
777
 
778
                        LOGGER.info("gift4 {}", gift);
779
                    }
780
                }
781
            }
782
 
783
 
784
        }
785
 
786
 
787
        //  LocalDateTime endDate = LocalDateTime.of(LocalDate.now().getYear(), LocalDate.now().getMonth(), 27, 21, 00);
788
 
32145 tejbeer 789
        ScratchOffer so2 = new ScratchOffer();
790
        so2.setInvoiceNumber(invoiceNumber);
791
        so2.setScratched(false);
792
        so2.setCreatedTimestamp(LocalDateTime.now());
32218 tejbeer 793
        so2.setExpiredTimestamp(LocalDateTime.now().plusDays(1));
794
        so2.setOfferName(gift);
32145 tejbeer 795
        so2.setCustomerId(customerId);
32218 tejbeer 796
        so2.setUnlockedAt(LocalDateTime.now());
32145 tejbeer 797
        LocalDate date = LocalDate.now();
32218 tejbeer 798
        /* LocalDateTime seven = LocalDateTime.of(date.getYear(), date.getMonth(), date.getDayOfMonth(), 19, 0);
32145 tejbeer 799
        LocalDateTime nine = LocalDateTime.of(date.getYear(), date.getMonth(), date.getDayOfMonth(), 21, 0);
32218 tejbeer 800
 
32145 tejbeer 801
        if (LocalDateTime.now().isAfter(seven)) {
32218 tejbeer 802
        so2.setUnlockedAt(nine.plusDays(1));
32145 tejbeer 803
        } else {
32218 tejbeer 804
        so2.setUnlockedAt(nine);
805
        }*/
31057 tejbeer 806
 
32218 tejbeer 807
 
32145 tejbeer 808
        scratchOfferRepository.persist(so2);
29515 tejbeer 809
 
32218 tejbeer 810
 
811
        ScratchOffer so = new ScratchOffer();
812
        so.setInvoiceNumber(invoiceNumber);
813
        so.setOfferName(ScratchedGift.EW);
814
        so.setScratched(false);
815
        so.setCreatedTimestamp(LocalDateTime.now());
816
        so.setExpiredTimestamp(so.getCreatedTimestamp().plusDays(1));
817
        so.setUnlockedAt(LocalDateTime.now());
818
        so.setCustomerId(customerId);
819
        scratchOfferRepository.persist(so);
820
 
821
 
32145 tejbeer 822
    }
29515 tejbeer 823
 
32145 tejbeer 824
    private HygieneData createAndGetHygieneData(int id, int fofoId) {
825
        HygieneData hygieneData = new HygieneData();
826
        hygieneData.setOrderId(id);
827
        hygieneData.setFofoId(fofoId);
828
        hygieneData.setCreatedTimestamp(LocalDateTime.now());
829
        hygieneDataRepository.persist(hygieneData);
25640 tejbeer 830
 
32145 tejbeer 831
        return hygieneData;
832
    }
25640 tejbeer 833
 
32145 tejbeer 834
    @Override
835
    public String getInvoiceNumber(int fofoId, String fofoStoreCode) {
836
        InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;
837
        try {
838
            invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);
839
            invoiceNumberGenerationSequence.setSequence(invoiceNumberGenerationSequence.getSequence() + 1);
840
        } catch (ProfitMandiBusinessException profitMandiBusinessException) {
841
            invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();
842
            invoiceNumberGenerationSequence.setFofoId(fofoId);
843
            invoiceNumberGenerationSequence.setPrefix(fofoStoreCode);
844
            invoiceNumberGenerationSequence.setSequence(1);
845
        }
846
        invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);
847
        return invoiceNumberGenerationSequence.getPrefix() + "/" + invoiceNumberGenerationSequence.getSequence();
848
    }
24275 amit.gupta 849
 
32145 tejbeer 850
    private String getSecurityDepositNumber(int fofoId, String fofoStoreCode) {
851
        InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;
852
        try {
853
            invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);
854
            invoiceNumberGenerationSequence.setChallanNumberSequence(invoiceNumberGenerationSequence.getChallanNumberSequence() + 1);
855
        } catch (ProfitMandiBusinessException profitMandiBusinessException) {
856
            invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();
857
            invoiceNumberGenerationSequence.setFofoId(fofoId);
858
            invoiceNumberGenerationSequence.setPrefix(fofoStoreCode);
859
            invoiceNumberGenerationSequence.setChallanNumberSequence(1);
860
        }
861
        invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);
862
        return invoiceNumberGenerationSequence.getPrefix() + "/SEC" + invoiceNumberGenerationSequence.getChallanNumberSequence();
863
    }
24226 amit.gupta 864
 
32145 tejbeer 865
    private Set<String> serialNumberDetailsToSerialNumbers(Set<SerialNumberDetail> serialNumberDetails) {
866
        Set<String> serialNumbers = new HashSet<>();
867
        for (SerialNumberDetail serialNumberDetail : serialNumberDetails) {
868
            if (serialNumberDetail.getSerialNumber() != null && !serialNumberDetail.getSerialNumber().isEmpty()) {
869
                serialNumbers.add(serialNumberDetail.getSerialNumber());
870
            }
871
        }
872
        return serialNumbers;
873
    }
23650 amit.gupta 874
 
32145 tejbeer 875
    @Override
876
    public InvoicePdfModel getInvoicePdfModel(int orderId) throws ProfitMandiBusinessException {
877
        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(orderId);
878
        return this.getInvoicePdfModel(fofoOrder);
879
    }
23650 amit.gupta 880
 
32145 tejbeer 881
    @Override
882
    @Cacheable(value = "order.dummymodel", cacheManager = "oneDayCacheManager")
883
    public InvoicePdfModel getDummyPdfModel(String serialNumber) throws ProfitMandiBusinessException {
884
        List<WarehouseInventoryItem> warehouseInventoryItems = warehouseInventoryItemRepository.selectWarehouseInventoryItemBySerailNumbers(Arrays.asList(serialNumber));
885
        if (warehouseInventoryItems.size() > 0) {
886
            WarehouseInventoryItem warehouseInventoryItem = warehouseInventoryItems.get(0);
887
            int currentQuantity = warehouseInventoryItems.get(0).getCurrentQuantity();
888
            if (currentQuantity > 0) {
889
                throw new ProfitMandiBusinessException("Serial Number", serialNumber, "Serial Number exist in our warehouse");
890
            } else {
891
                try {
892
                    InventoryItem inventoryItem = inventoryItemRepository.selectBySerialNumber(serialNumber);
893
                    if (inventoryItem.getGoodQuantity() > 0) {
894
                        throw new ProfitMandiBusinessException("Serial Number", serialNumber, "Serial Number is not yet billed by the partner");
895
                    } else {
896
                        List<ScanRecord> scanRecords = scanRecordRepository.selectByInventoryItemId(inventoryItem.getId());
897
                        Optional<ScanRecord> scanRecord = scanRecords.stream().filter(x -> x.getOrderId() != 0).findFirst();
898
                        if (scanRecord.isPresent()) {
899
                            FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(scanRecord.get().getOrderId());
900
                            orderIdsConsumed.add(fofoOrder.getId());
901
                            return this.getInvoicePdfModel(fofoOrder);
902
                        } else {
903
                            throw new ProfitMandiBusinessException("Serial Number", serialNumber, "Serial Number returned by partner, but in transit");
904
                        }
905
                    }
906
                } catch (Exception e) {
907
                    int itemId = warehouseInventoryItem.getItemId();
908
                    if (serialNumberOrderIdMap.containsKey(serialNumber)) {
909
                        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(serialNumberOrderIdMap.get(serialNumber));
910
                        InvoicePdfModel pdfModel = this.getInvoicePdfModel(fofoOrder.getId());
911
                        this.modifyDummyModel(fofoOrder, pdfModel, itemId, serialNumber);
912
                        return pdfModel;
913
                    }
914
                    // Map this serialNumber for dummy billing
915
                    LocalDateTime grnDate = warehouseInventoryItem.getCreated();
916
                    Random random = new Random();
917
                    int randomDays = random.ints(2, 15).findFirst().getAsInt();
918
                    LocalDateTime saleDate = grnDate.plusDays(randomDays);
919
                    if (saleDate.isAfter(LocalDate.now().atStartOfDay())) {
920
                        saleDate = LocalDateTime.now().minusDays(2);
921
                    }
922
                    Random offsetRandom = new Random();
923
                    int offset = offsetRandom.ints(2, 100).findFirst().getAsInt();
924
                    FofoOrder fofoOrder = fofoOrderRepository.selectFirstOrderAfterDate(saleDate, offset);
925
                    while (orderIdsConsumed.contains(fofoOrder.getId())) {
926
                        Random offsetRandom2 = new Random();
927
                        int offset2 = offsetRandom2.ints(2, 100).findFirst().getAsInt();
928
                        FofoOrder fofoOrder2 = fofoOrderRepository.selectFirstOrderAfterDate(saleDate, offset2);
929
                        if (fofoOrder2 != null) {
930
                            fofoOrder = fofoOrder2;
931
                        }
932
                    }
933
                    InvoicePdfModel pdfModel = this.getInvoicePdfModel(fofoOrder.getId());
934
                    orderIdsConsumed.add(fofoOrder.getId());
935
                    this.modifyDummyModel(fofoOrder, pdfModel, itemId, serialNumber);
936
                    return pdfModel;
27516 amit.gupta 937
 
32145 tejbeer 938
                }
939
            }
940
        } else {
941
            throw new ProfitMandiBusinessException("Serial Number", serialNumber, "Serial Number does not exist in our warehouse");
942
        }
943
    }
27516 amit.gupta 944
 
32145 tejbeer 945
    void modifyDummyModel(FofoOrder fofoOrder, InvoicePdfModel pdfModel, int itemId, String serialNumber) throws ProfitMandiBusinessException {
28166 tejbeer 946
 
32145 tejbeer 947
        int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoOrder.getFofoId());
27516 amit.gupta 948
 
32145 tejbeer 949
        Address retailerAddress = addressRepository.selectById(retailerAddressId);
950
        Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
27516 amit.gupta 951
 
32145 tejbeer 952
        CustomerAddress customerAddress = customer.getCustomerAddress().stream().filter(x -> x.getId() == fofoOrder.getCustomerAddressId()).findFirst().get();
27516 amit.gupta 953
 
32145 tejbeer 954
        Integer stateId = null;
955
        if (customerAddress.getState().equals(retailerAddress.getState())) {
956
            try {
957
                // stateId =
958
                // Long.valueOf(Utils.getStateInfo(customerAddress.getState()).getId()).intValue();
30527 tejbeer 959
 
32145 tejbeer 960
                stateId = Long.valueOf(stateRepository.selectByName(customerAddress.getState()).getId()).intValue();
961
            } catch (Exception e) {
962
                LOGGER.error("Unable to get state rates");
963
            }
964
        }
965
        CustomOrderItem cli = pdfModel.getOrderItems().stream().findFirst().get();
966
        List<FofoOrderItem> fofoOrderItems = Arrays.asList(this.getDummyFofoOrderItem(itemId, fofoOrder.getId(), serialNumber, stateId));
967
        pdfModel.setPaymentOptions(pdfModel.getPaymentOptions().stream().limit(1).collect(Collectors.toList()));
968
        CustomPaymentOption paymentOption = pdfModel.getPaymentOptions().get(0);
969
        paymentOption.setAmount(fofoOrderItems.get(0).getMop());
970
        Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();
971
        for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
972
            CustomOrderItem customFofoOrderItem = new CustomOrderItem();
973
            float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
974
            float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
975
            float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
27516 amit.gupta 976
 
32145 tejbeer 977
            customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));
978
            customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
979
            Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());
980
            // LOGGER.info("serialNumbers {}", serialNumbers);
981
            // LOGGER.info("serialNumbers is empty {}", serialNumbers.isEmpty());
982
            if (!serialNumbers.isEmpty()) {
983
                customFofoOrderItem.setDescription(
984
                        customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
985
            }
986
            customFofoOrderItem.setRate(taxableSellingPrice);
987
            customFofoOrderItem.setDiscount(taxableDiscountPrice);
988
            customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());
989
            customFofoOrderItem.setNetAmount(
990
                    (fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * fofoOrderItem.getQuantity());
991
            float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
992
            float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
993
            float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
994
            customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
995
            customFofoOrderItem.setIgstAmount(igstAmount);
996
            customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
997
            customFofoOrderItem.setCgstAmount(cgstAmount);
998
            customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
999
            customFofoOrderItem.setSgstAmount(sgstAmount);
1000
            customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
1001
            customerFofoOrderItems.add(customFofoOrderItem);
1002
        }
1003
        pdfModel.setTotalAmount(paymentOption.getAmount());
1004
        pdfModel.setOrderItems(customerFofoOrderItems);
28166 tejbeer 1005
 
32145 tejbeer 1006
    }
27516 amit.gupta 1007
 
32145 tejbeer 1008
    private InvoicePdfModel getInvoicePdfModel(FofoOrder fofoOrder) throws ProfitMandiBusinessException {
23650 amit.gupta 1009
 
32145 tejbeer 1010
        List<PaymentOptionTransaction> paymentOptionTransactions = paymentOptionTransactionRepository.selectByReferenceIdAndTypes(fofoOrder.getId(), Arrays.asList(PaymentOptionReferenceType.ORDER, PaymentOptionReferenceType.INSURANCE));
23650 amit.gupta 1011
 
32145 tejbeer 1012
        List<CustomPaymentOption> paymentOptions = new ArrayList<>();
23552 amit.gupta 1013
 
32145 tejbeer 1014
        InvoicePdfModel pdfModel = new InvoicePdfModel();
1015
        for (PaymentOptionTransaction paymentOptionTransaction : paymentOptionTransactions) {
1016
            CustomPaymentOption cpi = new CustomPaymentOption();
1017
            cpi.setAmount(paymentOptionTransaction.getAmount());
1018
            cpi.setPaymentOption(
1019
                    paymentOptionRepository.selectById(paymentOptionTransaction.getPaymentOptionId()).getName());
1020
            paymentOptions.add(cpi);
1021
        }
1022
        List<FofoOrderItem> fofoOrderItems = this.getByOrderId(fofoOrder.getId());
24215 amit.gupta 1023
 
32145 tejbeer 1024
        pdfModel.setTitle("Retailer Invoice");
1025
        Optional<FofoOrderItem> fofoOrderItemOptional = fofoOrderItems.stream().findAny();
1026
        if (fofoOrderItemOptional.isPresent() && fofoOrderItemOptional.get().equals("NOGST")) {
1027
            pdfModel.setTitle("Security Deposit Receipt");
1028
        }
1029
        pdfModel.setPaymentOptions(paymentOptions);
1030
        pdfModel.setAuther("SmartDukaan");
1031
        pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));
23650 amit.gupta 1032
 
32145 tejbeer 1033
        // insurance calculation
1034
        List<InsurancePolicy> insurancePolicies = insurancePolicyRepository.selectByRetailerIdInvoiceNumber(fofoOrder.getInvoiceNumber());
1035
        Set<CustomInsurancePolicy> customInsurancePolicies = new HashSet<>();
1036
        final float totalInsuranceTaxRate = 18;
1037
        for (InsurancePolicy insurancePolicy : insurancePolicies) {
1038
            float taxableInsurancePrice = insurancePolicy.getSaleAmount() / (1 + totalInsuranceTaxRate / 100);
1039
            CustomInsurancePolicy customInsurancePolicy = new CustomInsurancePolicy();
1040
            customInsurancePolicy.setDescription(insurancePolicy.getPolicyPlan() + " for Device #" + insurancePolicy.getSerialNumber() + "\n Plan Reference - " + insurancePolicy.getPolicyNumber());
1041
            customInsurancePolicy.setHsnCode("998716");
1042
            customInsurancePolicy.setRate(taxableInsurancePrice);
1043
            customInsurancePolicy.setIgstRate(18);
1044
            customInsurancePolicy.setIgstAmount(taxableInsurancePrice * 18 / 100);
1045
            customInsurancePolicy.setCgstRate(9);
1046
            customInsurancePolicy.setCgstAmount(taxableInsurancePrice * 9 / 100);
1047
            customInsurancePolicy.setSgstRate(9);
1048
            customInsurancePolicy.setSgstAmount(taxableInsurancePrice * 9 / 100);
1049
            customInsurancePolicy.setNetAmount(insurancePolicy.getSaleAmount());
1050
            customInsurancePolicies.add(customInsurancePolicy);
1051
        }
1052
        pdfModel.setInsurancePolicies(customInsurancePolicies);
24275 amit.gupta 1053
 
32145 tejbeer 1054
        pdfModel.setCustomer(getCustomCustomer(fofoOrder));
1055
        pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
1056
        pdfModel.setTotalAmount(fofoOrder.getTotalAmount());
23650 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
 
32145 tejbeer 1085
        Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();
1086
        for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
1087
            float discount = fofoOrderItem.getDiscount();
1088
            CustomOrderItem customFofoOrderItem = new CustomOrderItem();
1089
            float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
1090
            float taxableSellingPrice = (fofoOrderItem.getSellingPrice() + discount) / (1 + totalTaxRate / 100);
1091
            float taxableDiscountPrice = discount / (1 + totalTaxRate / 100);
23650 amit.gupta 1092
 
32145 tejbeer 1093
            customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));
1094
            customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
1095
            Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());
1096
            // LOGGER.info("serialNumbers {}", serialNumbers);
1097
            // LOGGER.info("serialNumbers is empty {}", serialNumbers.isEmpty());
1098
            if (!serialNumbers.isEmpty()) {
1099
                customFofoOrderItem.setDescription(
1100
                        customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
1101
            }
1102
            customFofoOrderItem.setRate(taxableSellingPrice);
1103
            customFofoOrderItem.setDiscount(taxableDiscountPrice);
1104
            customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());
1105
            customFofoOrderItem.setNetAmount(fofoOrderItem.getSellingPrice() * fofoOrderItem.getQuantity());
1106
            float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
1107
            float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
1108
            float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
1109
            customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
1110
            customFofoOrderItem.setIgstAmount(igstAmount);
1111
            customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
1112
            customFofoOrderItem.setCgstAmount(cgstAmount);
1113
            customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
1114
            customFofoOrderItem.setSgstAmount(sgstAmount);
1115
            customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
1116
            customerFofoOrderItems.add(customFofoOrderItem);
1117
        }
1118
        pdfModel.setOrderItems(customerFofoOrderItems);
1119
        String partnerAddressStateCode = stateRepository.selectByName(pdfModel.getRetailer().getAddress().getState()).getCode();
1120
        String customerAddressStateCode = stateRepository.selectByName(pdfModel.getCustomer().getAddress().getState()).getCode();
1121
        pdfModel.setPartnerAddressStateCode(partnerAddressStateCode);
1122
        pdfModel.setCustomerAddressStateCode(customerAddressStateCode);
1123
        pdfModel.setCancelled(fofoOrder.getCancelledTimestamp() != null);
1124
        List<String> tncs = new ArrayList<>();
1125
        tncs.add("I agree that goods received are in good working condition");
1126
        tncs.add("Goods once sold cannot be exchanged or taken back");
1127
        tncs.add("Warranty for the goods received by me is the responsibility of the manufacturer only.");
1128
        tncs.add("Customer needs to activate the handset at the time of delivery to be eligible for the discount");
1129
        tncs.add(
1130
                "Tempered Glass Replacement will be done only for the Mobile Phone which was purchased from SmartDukaan");
1131
        tncs.add(
1132
                "Customers requesting Tempered Glass Replacement will have to bring the broken tempered glass, either pasted on the phone or along with the phone");
1133
        tncs.add("Service fee of Rs.20 will be chargeable for each Tempered Glass Replacement");
1134
        if (pdfModel.getInsurancePolicies() != null && pdfModel.getInsurancePolicies().size() > 0) {
1135
            tncs.add("Damage protection provided is the responisibility of Protection Provider only");
1136
        }
1137
        pdfModel.setTncs(tncs);
1138
        return pdfModel;
23650 amit.gupta 1139
 
32145 tejbeer 1140
    }
23650 amit.gupta 1141
 
32145 tejbeer 1142
    private CustomCustomer getCustomCustomer(FofoOrder fofoOrder) throws ProfitMandiBusinessException {
1143
        Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
1144
        CustomCustomer customCustomer = new CustomCustomer();
1145
        customCustomer.setFirstName(customer.getFirstName());
1146
        customCustomer.setLastName(customer.getLastName());
1147
        customCustomer.setEmailId(customer.getEmailId());
1148
        customCustomer.setMobileNumber(customer.getMobileNumber());
1149
        customCustomer.setGstNumber(fofoOrder.getCustomerGstNumber());
1150
        CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());
1151
        customCustomer.setAddress(this.createCustomAddress(customerAddress));
1152
        return customCustomer;
1153
    }
23655 amit.gupta 1154
 
32145 tejbeer 1155
    @Override
1156
    public InvoicePdfModel getInvoicePdfModel(int fofoId, int orderId) throws ProfitMandiBusinessException {
1157
        FofoOrder fofoOrder = fofoOrderRepository.selectByFofoIdAndOrderId(fofoId, orderId);
1158
        return this.getInvoicePdfModel(fofoOrder);
1159
    }
23650 amit.gupta 1160
 
32145 tejbeer 1161
    public String getBillingAddress(CustomerAddress customerAddress) {
1162
        StringBuilder address = new StringBuilder();
1163
        if ((customerAddress.getLine1() != null) && (!customerAddress.getLine1().isEmpty())) {
1164
            address.append(customerAddress.getLine1());
1165
            address.append(", ");
1166
        }
22859 ashik.ali 1167
 
32145 tejbeer 1168
        if ((customerAddress.getLine2() != null) && (!customerAddress.getLine2().isEmpty())) {
1169
            address.append(customerAddress.getLine2());
1170
            address.append(", ");
1171
        }
22859 ashik.ali 1172
 
32145 tejbeer 1173
        if ((customerAddress.getLandmark() != null) && (!customerAddress.getLandmark().isEmpty())) {
1174
            address.append(customerAddress.getLandmark());
1175
            address.append(", ");
1176
        }
22859 ashik.ali 1177
 
32145 tejbeer 1178
        if ((customerAddress.getCity() != null) && (!customerAddress.getCity().isEmpty())) {
1179
            address.append(customerAddress.getCity());
1180
            address.append(", ");
1181
        }
22859 ashik.ali 1182
 
32145 tejbeer 1183
        if ((customerAddress.getState() != null) && (!customerAddress.getState().isEmpty())) {
1184
            address.append(customerAddress.getState());
1185
        }
22859 ashik.ali 1186
 
32145 tejbeer 1187
        if ((customerAddress.getPinCode() != null) && (!customerAddress.getPinCode().isEmpty())) {
1188
            address.append("- ");
1189
            address.append(customerAddress.getPinCode());
1190
        }
22859 ashik.ali 1191
 
32145 tejbeer 1192
        return address.toString();
1193
    }
23650 amit.gupta 1194
 
32145 tejbeer 1195
    @Override
1196
    public List<CartFofo> cartCheckout(String cartJson) throws ProfitMandiBusinessException {
1197
        try {
1198
            JSONObject cartObject = new JSONObject(cartJson);
1199
            Iterator<?> keys = cartObject.keys();
23650 amit.gupta 1200
 
32145 tejbeer 1201
            Set<Integer> itemIds = new HashSet<>();
1202
            List<CartFofo> cartItems = new ArrayList<CartFofo>();
23650 amit.gupta 1203
 
32145 tejbeer 1204
            while (keys.hasNext()) {
1205
                String key = (String) keys.next();
1206
                if (cartObject.get(key) instanceof JSONObject) {
1207
                    LOGGER.info(cartObject.get(key).toString());
1208
                }
1209
                CartFofo cf = new CartFofo();
1210
                cf.setItemId(cartObject.getJSONObject(key).getInt("itemId"));
1211
                cf.setQuantity(cartObject.getJSONObject(key).getInt("quantity"));
1212
                if (cartObject.getJSONObject(key).has("poId")) {
23650 amit.gupta 1213
 
32145 tejbeer 1214
                    cf.setPoId(cartObject.getJSONObject(key).getInt("poId"));
1215
                    cf.setPoItemId(cartObject.getJSONObject(key).getInt("poItemId"));
1216
                }
1217
                if (cf.getQuantity() <= 0) {
1218
                    continue;
1219
                }
1220
                cartItems.add(cf);
1221
                itemIds.add(cartObject.getJSONObject(key).getInt("itemId"));
1222
            }
1223
            Map<Integer, Item> itemMap = new HashMap<Integer, Item>();
1224
            if (itemIds.size() > 0) {
1225
                List<Item> items = itemRepository.selectByIds(itemIds);
1226
                for (Item i : items) {
1227
                    itemMap.put(i.getId(), i);
1228
                }
23650 amit.gupta 1229
 
32145 tejbeer 1230
            }
1231
            for (CartFofo cf : cartItems) {
1232
                Item i = itemMap.get(cf.getItemId());
1233
                if (i == null) {
1234
                    continue;
1235
                }
1236
                cf.setDisplayName(getValidName(i.getBrand()) + " " + getValidName(i.getModelName()) + " " + getValidName(i.getModelNumber()) + " " + getValidName(i.getColor()).replaceAll("\\s+", " "));
1237
                cf.setItemType(i.getType());
1238
            }
1239
            return cartItems;
1240
        } catch (Exception e) {
1241
            LOGGER.error("Unable to Prepare cart to place order...", e);
1242
            throw new ProfitMandiBusinessException("cartData", cartJson, "FFORDR_1006");
1243
        }
1244
    }
23650 amit.gupta 1245
 
32145 tejbeer 1246
    @Override
1247
    public Map<String, Object> getSaleHistory(int fofoId, SearchType searchType, String searchValue, LocalDateTime startDate, LocalDateTime endDate, int offset, int limit) throws ProfitMandiBusinessException {
1248
        long countItems = 0;
1249
        List<FofoOrder> fofoOrders = new ArrayList<>();
23650 amit.gupta 1250
 
32145 tejbeer 1251
        if (searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()) {
1252
            fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, null, null, offset, limit);
1253
            countItems = fofoOrderRepository.selectCountByCustomerMobileNumber(fofoId, searchValue, null, null);
1254
        } else if (searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()) {
1255
            fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, null, null, offset, limit);
1256
            countItems = fofoOrderRepository.selectCountByCustomerName(fofoId, searchValue, null, null);
1257
        } else if (searchType == SearchType.IMEI && !searchValue.isEmpty()) {
1258
            fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, null, null, offset, limit);
1259
            countItems = fofoOrderRepository.selectCountBySerialNumber(fofoId, searchValue, null, null);
1260
        } else if (searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()) {
1261
            fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, null, null, offset, limit);
1262
            countItems = fofoOrderRepository.selectCountByItemName(fofoId, searchValue, null, null);
1263
        } else if (searchType == SearchType.INVOICE_NUMBER && !searchValue.isEmpty()) {
1264
            fofoOrders = Arrays.asList(fofoOrderRepository.selectByFofoIdAndInvoiceNumber(fofoId, searchValue));
1265
            countItems = fofoOrders.size();
1266
        } else if (searchType == SearchType.DATE_RANGE) {
1267
            fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDate, endDate, offset, limit);
1268
            countItems = fofoOrderRepository.selectCountByFofoId(fofoId, startDate, endDate);
1269
        }
1270
        Map<String, Object> map = new HashMap<>();
23650 amit.gupta 1271
 
32145 tejbeer 1272
        map.put("saleHistories", fofoOrders);
1273
        map.put("start", offset + 1);
1274
        map.put("size", countItems);
1275
        map.put("searchType", searchType);
1276
        map.put("searchTypes", SearchType.values());
1277
        map.put("startDate", startDate);
1278
        map.put("searchValue", searchValue);
1279
        map.put(ProfitMandiConstants.END_TIME, endDate);
1280
        if (fofoOrders.size() < limit) {
1281
            map.put("end", offset + fofoOrders.size());
1282
        } else {
1283
            map.put("end", offset + limit);
1284
        }
1285
        return map;
1286
    }
30426 tejbeer 1287
 
32145 tejbeer 1288
    public ResponseEntity<?> downloadReportInCsv(org.apache.commons.io.output.ByteArrayOutputStream baos, List<List<?>> rows, String fileName) {
1289
        final HttpHeaders headers = new HttpHeaders();
1290
        headers.set("Content-Type", "text/csv");
30426 tejbeer 1291
 
32145 tejbeer 1292
        headers.set("Content-disposition", "inline; filename=" + fileName + ".csv");
1293
        headers.setContentLength(baos.toByteArray().length);
23202 ashik.ali 1294
 
32145 tejbeer 1295
        final InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
1296
        final InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
30426 tejbeer 1297
 
32145 tejbeer 1298
        return new ResponseEntity<InputStreamResource>(inputStreamResource, headers, HttpStatus.OK);
1299
    }
30157 manish 1300
 
32145 tejbeer 1301
    @Override
1302
    public Map<String, Object> getSaleHistoryPaginated(int fofoId, SearchType searchType, String searchValue, LocalDateTime startDate, LocalDateTime endDate, int offset, int limit) throws ProfitMandiBusinessException {
1303
        List<FofoOrder> fofoOrders = new ArrayList<>();
23650 amit.gupta 1304
 
32145 tejbeer 1305
        if (searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()) {
1306
            fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, startDate, endDate, offset, limit);
1307
        } else if (searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()) {
1308
            fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, startDate, endDate, offset, limit);
1309
        } else if (searchType == SearchType.IMEI && !searchValue.isEmpty()) {
1310
            fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, startDate, endDate, offset, limit);
1311
        } else if (searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()) {
1312
            fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, startDate, endDate, offset, limit);
24275 amit.gupta 1313
 
32145 tejbeer 1314
        } else if (searchType == SearchType.DATE_RANGE) {
1315
            fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDate, endDate, offset, limit);
1316
        }
1317
        Map<String, Object> map = new HashMap<>();
1318
        map.put("saleHistories", fofoOrders);
1319
        map.put("searchType", searchType);
1320
        map.put("searchTypes", SearchType.values());
1321
        map.put("startDate", startDate);
1322
        map.put("searchValue", searchValue);
1323
        map.put(ProfitMandiConstants.END_TIME, endDate);
1324
        return map;
1325
    }
23650 amit.gupta 1326
 
32145 tejbeer 1327
    private String getFofoStoreCode(int fofoId) throws ProfitMandiBusinessException {
1328
        FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
1329
        return fofoStore.getCode();
1330
    }
23650 amit.gupta 1331
 
32145 tejbeer 1332
    private String getValidName(String name) {
1333
        return name != null ? name : "";
1334
    }
23650 amit.gupta 1335
 
32145 tejbeer 1336
    private Set<String> toSerialNumbers(Set<FofoLineItem> fofoLineItems) {
1337
        Set<String> serialNumbers = new HashSet<>();
1338
        for (FofoLineItem fofoLineItem : fofoLineItems) {
1339
            if (fofoLineItem.getSerialNumber() != null && !fofoLineItem.getSerialNumber().isEmpty()) {
1340
                serialNumbers.add(fofoLineItem.getSerialNumber());
1341
            }
1342
        }
1343
        return serialNumbers;
1344
    }
23650 amit.gupta 1345
 
32145 tejbeer 1346
    private void validateDpPrice(Map<Integer, PriceModel> itemIdMopPriceMap, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException {
1347
        for (Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoLineItemMap.entrySet()) {
1348
            int itemId = entry.getKey();
1349
            CustomFofoOrderItem customFofoOrderItem = entry.getValue();
1350
            LOGGER.info("CustomFofoOrderItem -- {}", customFofoOrderItem);
1351
            PriceModel priceModel = itemIdMopPriceMap.get(itemId);
1352
            Item item = itemRepository.selectById(itemId);
1353
            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) {
1354
                if (Utils.compareFloat(priceModel.getPrice(), customFofoOrderItem.getSellingPrice() + customFofoOrderItem.getDiscountAmount()) > 0) {
1355
                    throw new ProfitMandiBusinessException("Selling Price for ", item.getItemDescription(), "FFORDR_1010");
1356
                }
1357
            } else {
1358
                if (!item.getBrand().equals("Live Demo") && priceModel.getPurchasePrice() > customFofoOrderItem.getSellingPrice()) {
1359
                    throw new ProfitMandiBusinessException("Selling Price", itemRepository.selectById(itemId).getItemDescription(), "Selling Price should not be less than DP");
1360
                }
1361
            }
1362
        }
1363
    }
24275 amit.gupta 1364
 
32145 tejbeer 1365
    private void validateMopPrice(Map<Integer, PriceModel> itemIdMopPriceMap, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException {
1366
        Map<Integer, Float> invalidMopItemIdPriceMap = new HashMap<>();
1367
        for (Map.Entry<Integer, PriceModel> entry : itemIdMopPriceMap.entrySet()) {
1368
            CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoLineItemMap.get(entry.getKey());
1369
            Item item = itemRepository.selectById(customFofoOrderItem.getItemId());
1370
            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()) {
1371
                invalidMopItemIdPriceMap.put(entry.getKey(), customFofoOrderItem.getSellingPrice());
1372
            }
1373
        }
23650 amit.gupta 1374
 
32145 tejbeer 1375
        if (!invalidMopItemIdPriceMap.isEmpty()) {
1376
            LOGGER.error("Invalid itemIds selling prices{} should be greater than mop prices {}", invalidMopItemIdPriceMap, itemIdMopPriceMap);
1377
            throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidMopItemIdPriceMap, "FFORDR_1010");
1378
        }
23650 amit.gupta 1379
 
32145 tejbeer 1380
    }
23650 amit.gupta 1381
 
32145 tejbeer 1382
    private void updateInventoryItemsAndScanRecord(Set<InventoryItem> inventoryItems, int fofoId, Map<Integer, Integer> inventoryItemQuantityUsed, int fofoOrderId) {
1383
        for (InventoryItem inventoryItem : inventoryItems) {
1384
            inventoryItem.setLastScanType(ScanType.SALE);
1385
            ScanRecord scanRecord = new ScanRecord();
1386
            scanRecord.setInventoryItemId(inventoryItem.getId());
1387
            scanRecord.setFofoId(fofoId);
1388
            scanRecord.setOrderId(fofoOrderId);
1389
            // correct this
1390
            scanRecord.setQuantity(inventoryItemQuantityUsed.get(inventoryItem.getId()));
1391
            scanRecord.setType(ScanType.SALE);
1392
            scanRecordRepository.persist(scanRecord);
1393
            purchaseReturnItemRepository.deleteById(inventoryItem.getId());
23650 amit.gupta 1394
 
32145 tejbeer 1395
        }
1396
    }
23650 amit.gupta 1397
 
32145 tejbeer 1398
    private void createFofoLineItem(int fofoOrderItemId, Set<InventoryItem> inventoryItems, Map<Integer, Integer> inventoryItemIdQuantityUsed) {
1399
        for (InventoryItem inventoryItem : inventoryItems) {
1400
            FofoLineItem fofoLineItem = new FofoLineItem();
1401
            fofoLineItem.setFofoOrderItemId(fofoOrderItemId);
1402
            fofoLineItem.setSerialNumber(inventoryItem.getSerialNumber());
1403
            fofoLineItem.setInventoryItemId(inventoryItem.getId());
1404
            fofoLineItem.setQuantity(inventoryItemIdQuantityUsed.get(inventoryItem.getId()));
1405
            fofoLineItemRepository.persist(fofoLineItem);
1406
        }
1407
    }
23650 amit.gupta 1408
 
32145 tejbeer 1409
    private FofoOrderItem createAndGetFofoOrderItem(CustomFofoOrderItem customFofoOrderItem, int fofoOrderId, Map<Integer, Item> itemMap, Set<InventoryItem> inventoryItems, Integer stateId) throws ProfitMandiBusinessException {
1410
        FofoOrderItem fofoOrderItem = new FofoOrderItem();
1411
        fofoOrderItem.setItemId(customFofoOrderItem.getItemId());
1412
        fofoOrderItem.setQuantity(customFofoOrderItem.getQuantity());
1413
        fofoOrderItem.setSellingPrice(customFofoOrderItem.getSellingPrice());
1414
        fofoOrderItem.setOrderId(fofoOrderId);
1415
        TagListing tl = tagListingRepository.selectByItemId(customFofoOrderItem.getItemId());
1416
        // In case listing gets removed rebill it using the selling price
1417
        if (tl != null) {
1418
            fofoOrderItem.setDp(tl.getSellingPrice());
1419
            fofoOrderItem.setMop(tl.getMop());
1420
        } else {
1421
            fofoOrderItem.setDp(customFofoOrderItem.getSellingPrice());
1422
            fofoOrderItem.setMop(customFofoOrderItem.getSellingPrice());
1423
        }
1424
        fofoOrderItem.setDiscount(customFofoOrderItem.getDiscountAmount());
24823 amit.gupta 1425
 
32145 tejbeer 1426
        Item item = itemMap.get(customFofoOrderItem.getItemId());
1427
        Map<Integer, GstRate> itemIdStateTaxRateMap = null;
1428
        if (stateId != null) {
1429
            itemIdStateTaxRateMap = stateGstRateRepository.getStateTaxRate(new ArrayList<>(itemMap.keySet()), stateId);
1430
        } else {
1431
            itemIdStateTaxRateMap = stateGstRateRepository.getIgstTaxRate(new ArrayList<>(itemMap.keySet()));
1432
        }
1433
        for (InventoryItem inventoryItem : inventoryItems) {
23650 amit.gupta 1434
 
32145 tejbeer 1435
            fofoOrderItem.setIgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getIgstRate());
23650 amit.gupta 1436
 
32145 tejbeer 1437
            fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getCgstRate());
1438
            fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getSgstRate());
27516 amit.gupta 1439
 
1440
 
32145 tejbeer 1441
            fofoOrderItem.setHsnCode(inventoryItem.getHsnCode());
1442
            break;
1443
        }
1444
        fofoOrderItem.setBrand(item.getBrand());
1445
        fofoOrderItem.setModelName(item.getModelName());
1446
        fofoOrderItem.setModelNumber(item.getModelNumber());
1447
        fofoOrderItem.setColor(item.getColor());
1448
        fofoOrderItemRepository.persist(fofoOrderItem);
1449
        return fofoOrderItem;
1450
    }
27516 amit.gupta 1451
 
32145 tejbeer 1452
    private FofoOrderItem getDummyFofoOrderItem(int itemId, int fofoOrderId, String serialNumber, Integer stateId) throws ProfitMandiBusinessException {
1453
        Item item = itemRepository.selectById(itemId);
1454
        TagListing tl = tagListingRepository.selectByItemId(itemId);
1455
        FofoOrderItem fofoOrderItem = new FofoOrderItem();
1456
        fofoOrderItem.setItemId(itemId);
1457
        fofoOrderItem.setQuantity(1);
1458
        fofoOrderItem.setSellingPrice(tl.getMop());
1459
        fofoOrderItem.setOrderId(fofoOrderId);
1460
        // In case listing gets removed rebill it using the selling price
1461
        fofoOrderItem.setDp(tl.getSellingPrice());
1462
        fofoOrderItem.setMop(tl.getMop());
1463
        fofoOrderItem.setDiscount(0);
27516 amit.gupta 1464
 
32145 tejbeer 1465
        Map<Integer, GstRate> itemIdStateTaxRateMap = null;
1466
        if (stateId != null) {
1467
            itemIdStateTaxRateMap = stateGstRateRepository.getStateTaxRate(Arrays.asList(itemId), stateId);
1468
        } else {
1469
            itemIdStateTaxRateMap = stateGstRateRepository.getIgstTaxRate(Arrays.asList(itemId));
1470
        }
27516 amit.gupta 1471
 
32145 tejbeer 1472
        fofoOrderItem.setIgstRate(itemIdStateTaxRateMap.get(itemId).getIgstRate());
27516 amit.gupta 1473
 
32145 tejbeer 1474
        fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(itemId).getCgstRate());
1475
        fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(itemId).getSgstRate());
23650 amit.gupta 1476
 
1477
 
32145 tejbeer 1478
        fofoOrderItem.setHsnCode(item.getHsnCode());
1479
        fofoOrderItem.setBrand(item.getBrand());
1480
        fofoOrderItem.setModelName(item.getModelName());
1481
        fofoOrderItem.setModelNumber(item.getModelNumber());
1482
        fofoOrderItem.setColor(item.getColor());
23650 amit.gupta 1483
 
32145 tejbeer 1484
        Set<FofoLineItem> fofoLineItems = new HashSet<>();
1485
        FofoLineItem fli = new FofoLineItem();
1486
        fli.setQuantity(1);
1487
        fli.setSerialNumber(serialNumber);
1488
        fofoLineItems.add(fli);
1489
        fofoOrderItem.setFofoLineItems(fofoLineItems);
22859 ashik.ali 1490
 
32145 tejbeer 1491
        return fofoOrderItem;
1492
    }
22859 ashik.ali 1493
 
32145 tejbeer 1494
    private void updateCurrentInventorySnapshot(List<CurrentInventorySnapshot> currentInventorySnapshots, int fofoId, int itemId, int quantity) throws ProfitMandiBusinessException {
1495
        for (CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {
1496
            if (currentInventorySnapshot.getItemId() == itemId && currentInventorySnapshot.getFofoId() == fofoId) {
1497
                currentInventorySnapshotRepository.updateAvailabilityByItemIdAndFofoId(itemId, fofoId, currentInventorySnapshot.getAvailability() - quantity);
1498
            }
1499
        }
1500
    }
23650 amit.gupta 1501
 
32145 tejbeer 1502
    private void createPaymentOptions(FofoOrder fofoOrder, Set<CustomPaymentOption> customPaymentOptions) throws ProfitMandiBusinessException {
1503
        for (CustomPaymentOption customPaymentOption : customPaymentOptions) {
1504
            if (customPaymentOption.getAmount() > 0) {
1505
                PaymentOptionTransaction paymentOptionTransaction = new PaymentOptionTransaction();
1506
                paymentOptionTransaction.setReferenceId(fofoOrder.getId());
1507
                paymentOptionTransaction.setPaymentOptionId(customPaymentOption.getPaymentOptionId());
1508
                paymentOptionTransaction.setReferenceType(PaymentOptionReferenceType.ORDER);
1509
                paymentOptionTransaction.setAmount(customPaymentOption.getAmount());
1510
                paymentOptionTransaction.setFofoId(fofoOrder.getFofoId());
1511
                paymentOptionTransactionRepository.persist(paymentOptionTransaction);
1512
            }
1513
        }
1514
    }
22859 ashik.ali 1515
 
32145 tejbeer 1516
    private FofoOrder createAndGetFofoOrder(int customerId, String customerGstNumber, int fofoId, String documentNumber, float totalAmount, int customerAddressId) {
1517
        FofoOrder fofoOrder = new FofoOrder();
1518
        fofoOrder.setCustomerGstNumber(customerGstNumber);
1519
        fofoOrder.setCustomerId(customerId);
1520
        fofoOrder.setFofoId(fofoId);
1521
        fofoOrder.setInvoiceNumber(documentNumber);
1522
        fofoOrder.setTotalAmount(totalAmount);
1523
        fofoOrder.setCustomerAddressId(customerAddressId);
1524
        fofoOrderRepository.persist(fofoOrder);
1525
        return fofoOrder;
1526
    }
23650 amit.gupta 1527
 
32145 tejbeer 1528
    private void validateItemsSerializedNonSerialized(List<Item> items, Map<Integer, CustomFofoOrderItem> customFofoOrderItemMap) throws ProfitMandiBusinessException {
1529
        List<Integer> invalidItemIdSerialNumbers = new ArrayList<Integer>();
1530
        List<Integer> itemIdNonSerializedSerialNumbers = new ArrayList<Integer>();
1531
        for (Item i : items) {
1532
            CustomFofoOrderItem customFofoOrderItem = customFofoOrderItemMap.get(i.getId());
1533
            if (i.getType().equals(ItemType.SERIALIZED)) {
1534
                if (customFofoOrderItem == null || customFofoOrderItem.getSerialNumberDetails().isEmpty()) {
1535
                    invalidItemIdSerialNumbers.add(i.getId());
1536
                }
1537
            } else {
1538
                Set<String> serialNumbers = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());
1539
                if (customFofoOrderItem == null || !serialNumbers.isEmpty()) {
1540
                    itemIdNonSerializedSerialNumbers.add(i.getId());
1541
                }
1542
            }
1543
        }
23650 amit.gupta 1544
 
32145 tejbeer 1545
        if (!invalidItemIdSerialNumbers.isEmpty()) {
1546
            LOGGER.error("Invalid itemId's serialNumbers for serialized{}", invalidItemIdSerialNumbers);
1547
            // itemId's are serialized you are saying these are not serialized
1548
            throw new ProfitMandiBusinessException("invalidItemIdSerialNumbers", invalidItemIdSerialNumbers, "FFORDR_1013");
1549
        }
22859 ashik.ali 1550
 
32145 tejbeer 1551
        if (!itemIdNonSerializedSerialNumbers.isEmpty()) {
1552
            LOGGER.error("Invalid itemId's serialNumbers for non serialized{}", itemIdNonSerializedSerialNumbers);
1553
            // itemId's are non serialized you are saying these are serialized
1554
            throw new ProfitMandiBusinessException("itemIdNonSerializedSerialNumbers", itemIdNonSerializedSerialNumbers, "FFORDR_1014");
1555
        }
1556
    }
22859 ashik.ali 1557
 
32145 tejbeer 1558
    private void validateCurrentInventorySnapshotQuantities(List<CurrentInventorySnapshot> currentInventorySnapshots, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap) throws ProfitMandiBusinessException {
1559
        if (itemIdCustomFofoOrderItemMap.keySet().size() != currentInventorySnapshots.size()) {
1560
            throw new ProfitMandiBusinessException("quantiiesSize", currentInventorySnapshots.size(), "");
1561
        }
1562
        List<ItemIdQuantityAvailability> itemIdQuantityAvailabilities = new ArrayList<>(); // this is for error
1563
        LOGGER.info("currentInventorySnapshots " + currentInventorySnapshots);
1564
        LOGGER.info("CustomFofoLineItemMap {}", itemIdCustomFofoOrderItemMap);
1565
        for (CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {
1566
            CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoOrderItemMap.get(currentInventorySnapshot.getItemId());
1567
            LOGGER.info("customFofoOrderItem {}", customFofoOrderItem);
1568
            if (customFofoOrderItem.getQuantity() > currentInventorySnapshot.getAvailability()) {
1569
                ItemIdQuantityAvailability itemIdQuantityAvailability = new ItemIdQuantityAvailability();
1570
                itemIdQuantityAvailability.setItemId(customFofoOrderItem.getItemId());
1571
                Quantity quantity = new Quantity();
1572
                quantity.setAvailable(currentInventorySnapshot.getAvailability());
1573
                quantity.setRequested(customFofoOrderItem.getQuantity());
1574
                itemIdQuantityAvailability.setQuantity(quantity);
1575
                itemIdQuantityAvailabilities.add(itemIdQuantityAvailability);
1576
            }
1577
        }
22859 ashik.ali 1578
 
32145 tejbeer 1579
        if (!itemIdQuantityAvailabilities.isEmpty()) {
1580
            // itemIdQuantity request is not valid
1581
            LOGGER.error("Requested quantities should not be greater than currently available quantities {}", itemIdQuantityAvailabilities);
1582
            throw new ProfitMandiBusinessException("itemIdQuantityAvailabilities", itemIdQuantityAvailabilities, "FFORDR_1015");
1583
        }
1584
    }
22859 ashik.ali 1585
 
32145 tejbeer 1586
    private int getItemIdFromSerialNumber(Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap, String serialNumber) {
1587
        int itemId = 0;
1588
        for (Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoOrderItemMap.entrySet()) {
1589
            Set<SerialNumberDetail> serialNumberDetails = entry.getValue().getSerialNumberDetails();
1590
            for (SerialNumberDetail serialNumberDetail : serialNumberDetails) {
1591
                if (serialNumberDetail.getSerialNumber().equals(serialNumber)) {
1592
                    itemId = entry.getKey();
1593
                    break;
1594
                }
1595
            }
1596
        }
1597
        return itemId;
1598
    }
23650 amit.gupta 1599
 
32145 tejbeer 1600
    private Map<Integer, Item> toItemMap(List<Item> items) {
1601
        Function<Item, Integer> itemIdFunction = new Function<Item, Integer>() {
1602
            @Override
1603
            public Integer apply(Item item) {
1604
                return item.getId();
1605
            }
1606
        };
1607
        Function<Item, Item> itemFunction = new Function<Item, Item>() {
1608
            @Override
1609
            public Item apply(Item item) {
1610
                return item;
1611
            }
1612
        };
1613
        return items.stream().collect(Collectors.toMap(itemIdFunction, itemFunction));
1614
    }
23650 amit.gupta 1615
 
32145 tejbeer 1616
    private void setCustomerAddress(CustomerAddress customerAddress, CustomAddress customAddress) {
1617
        customerAddress.setName(customAddress.getName());
1618
        customerAddress.setLastName(customAddress.getLastName());
1619
        customerAddress.setLine1(customAddress.getLine1());
1620
        customerAddress.setLine2(customAddress.getLine2());
1621
        customerAddress.setLandmark(customAddress.getLandmark());
1622
        customerAddress.setCity(customAddress.getCity());
1623
        customerAddress.setPinCode(customAddress.getPinCode());
1624
        customerAddress.setState(customAddress.getState());
1625
        customerAddress.setCountry(customAddress.getCountry());
1626
        customerAddress.setPhoneNumber(customAddress.getPhoneNumber());
1627
    }
23650 amit.gupta 1628
 
32145 tejbeer 1629
    private CustomAddress createCustomAddress(Address address) {
1630
        CustomAddress customAddress = new CustomAddress();
1631
        customAddress.setName(address.getName());
1632
        customAddress.setLine1(address.getLine1());
1633
        customAddress.setLine2(address.getLine2());
1634
        customAddress.setLandmark(address.getLandmark());
1635
        customAddress.setCity(address.getCity());
1636
        customAddress.setPinCode(address.getPinCode());
1637
        customAddress.setState(address.getState());
1638
        customAddress.setCountry(address.getCountry());
1639
        customAddress.setPhoneNumber(address.getPhoneNumber());
1640
        return customAddress;
1641
    }
23650 amit.gupta 1642
 
32145 tejbeer 1643
    private CustomAddress createCustomAddress(CustomerAddress customerAddress) {
1644
        CustomAddress customAddress = new CustomAddress();
1645
        customAddress.setName(customerAddress.getName());
1646
        customAddress.setLastName(customerAddress.getLastName());
1647
        customAddress.setLine1(customerAddress.getLine1());
1648
        customAddress.setLine2(customerAddress.getLine2());
1649
        customAddress.setLandmark(customerAddress.getLandmark());
1650
        customAddress.setCity(customerAddress.getCity());
1651
        customAddress.setPinCode(customerAddress.getPinCode());
1652
        customAddress.setState(customerAddress.getState());
1653
        customAddress.setCountry(customerAddress.getCountry());
1654
        customAddress.setPhoneNumber(customerAddress.getPhoneNumber());
1655
        return customAddress;
1656
    }
23650 amit.gupta 1657
 
32145 tejbeer 1658
    private void validatePaymentOptionsAndTotalAmount(Set<CustomPaymentOption> customPaymentOptions, float totalAmount) throws ProfitMandiBusinessException {
1659
        Set<Integer> paymentOptionIds = new HashSet<>();
23650 amit.gupta 1660
 
32145 tejbeer 1661
        float calculatedAmount = 0;
1662
        for (CustomPaymentOption customPaymentOption : customPaymentOptions) {
1663
            paymentOptionIds.add(customPaymentOption.getPaymentOptionId());
1664
            calculatedAmount = calculatedAmount + customPaymentOption.getAmount();
1665
        }
1666
        if (calculatedAmount != totalAmount) {
1667
            LOGGER.warn("Error occured while validating payment options amount - {} != TotalAmount {}", calculatedAmount, totalAmount);
1668
            throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_CALCULATED_AMOUNT, calculatedAmount, "FFORDR_1016");
1669
        }
23418 ashik.ali 1670
 
32145 tejbeer 1671
        List<Integer> foundPaymentOptionIds = paymentOptionRepository.selectIdsByIds(paymentOptionIds);
1672
        if (foundPaymentOptionIds.size() != paymentOptionIds.size()) {
1673
            paymentOptionIds.removeAll(foundPaymentOptionIds);
1674
            throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_ID, paymentOptionIds, "FFORDR_1017");
1675
        }
1676
    }
25101 amit.gupta 1677
 
32145 tejbeer 1678
    @Override
1679
    public List<FofoOrderItem> getByOrderId(int orderId) throws ProfitMandiBusinessException {
1680
        List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(orderId);
1681
        if (!fofoOrderItems.isEmpty()) {
1682
            List<FofoOrderItem> newFofoOrderItems = new ArrayList<>();
1683
            Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = this.toFofoOrderItemIdFofoLineItems(fofoOrderItems);
1684
            Iterator<FofoOrderItem> fofoOrderItemsIterator = fofoOrderItems.iterator();
1685
            while (fofoOrderItemsIterator.hasNext()) {
1686
                FofoOrderItem fofoOrderItem = fofoOrderItemsIterator.next();
1687
                fofoOrderItem.setFofoLineItems(fofoOrderItemIdFofoLineItemsMap.get(fofoOrderItem.getId()));
1688
                newFofoOrderItems.add(fofoOrderItem);
1689
                fofoOrderItemsIterator.remove();
1690
            }
1691
            fofoOrderItems = newFofoOrderItems;
1692
        }
1693
        return fofoOrderItems;
1694
    }
25101 amit.gupta 1695
 
32145 tejbeer 1696
    private Set<Integer> toFofoOrderItemIds(List<FofoOrderItem> fofoOrderItems) {
1697
        Function<FofoOrderItem, Integer> fofoOrderItemToFofoOrderItemIdFunction = new Function<FofoOrderItem, Integer>() {
1698
            @Override
1699
            public Integer apply(FofoOrderItem fofoOrderItem) {
1700
                return fofoOrderItem.getId();
1701
            }
1702
        };
1703
        return fofoOrderItems.stream().map(fofoOrderItemToFofoOrderItemIdFunction).collect(Collectors.toSet());
1704
    }
25101 amit.gupta 1705
 
32145 tejbeer 1706
    private Map<Integer, Set<FofoLineItem>> toFofoOrderItemIdFofoLineItems(List<FofoOrderItem> fofoOrderItems) {
1707
        Set<Integer> fofoOrderItemIds = this.toFofoOrderItemIds(fofoOrderItems);
1708
        List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIds);
1709
        Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = new HashMap<>();
1710
        for (FofoLineItem fofoLineItem : fofoLineItems) {
1711
            if (!fofoOrderItemIdFofoLineItemsMap.containsKey(fofoLineItem.getFofoOrderItemId())) {
1712
                Set<FofoLineItem> fofoLineItems2 = new HashSet<>();
1713
                fofoLineItems2.add(fofoLineItem);
1714
                fofoOrderItemIdFofoLineItemsMap.put(fofoLineItem.getFofoOrderItemId(), fofoLineItems2);
1715
            } else {
1716
                fofoOrderItemIdFofoLineItemsMap.get(fofoLineItem.getFofoOrderItemId()).add(fofoLineItem);
1717
            }
1718
        }
1719
        return fofoOrderItemIdFofoLineItemsMap;
1720
    }
25101 amit.gupta 1721
 
32145 tejbeer 1722
    @Override
1723
    public void updateCustomerDetails(CustomCustomer customCustomer, String invoiceNumber) throws ProfitMandiBusinessException {
1724
        FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
1725
        Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
1726
        customer.setFirstName(customCustomer.getFirstName());
1727
        customer.setLastName(customCustomer.getLastName());
1728
        customer.setMobileNumber(customCustomer.getMobileNumber());
1729
        customer.setEmailId(customCustomer.getEmailId());
1730
        customerRepository.persist(customer);
1731
        CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());
1732
        if (!customerAddress.getState().equalsIgnoreCase(customCustomer.getAddress().getState())) {
1733
            List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
1734
            resetTaxation(fofoOrder.getFofoId(), customerAddress, fofoOrderItems);
1735
        }
1736
        this.setCustomerAddress(customerAddress, customCustomer.getAddress());
1737
        customerAddressRepository.persist(customerAddress);
1738
        fofoOrder.setCustomerGstNumber(customCustomer.getGstNumber());
1739
    }
23638 amit.gupta 1740
 
32145 tejbeer 1741
    private void resetTaxation(int fofoId, CustomerAddress customerAddress, List<FofoOrderItem> fofoOrderItems) throws ProfitMandiBusinessException {
1742
        int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoId);
23650 amit.gupta 1743
 
32145 tejbeer 1744
        Address retailerAddress = addressRepository.selectById(retailerAddressId);
24275 amit.gupta 1745
 
32145 tejbeer 1746
        Integer stateId = null;
1747
        if (customerAddress.getState().equalsIgnoreCase(retailerAddress.getState())) {
1748
            try {
1749
                stateId = Long.valueOf(stateRepository.selectByName(customerAddress.getState()).getId()).intValue();
1750
            } catch (Exception e) {
1751
                LOGGER.error("Unable to get state rates");
1752
            }
1753
        }
1754
        List<Integer> itemIds = fofoOrderItems.stream().map(x -> x.getItemId()).collect(Collectors.toList());
1755
        final Map<Integer, GstRate> gstRates;
1756
        if (stateId != null) {
1757
            gstRates = stateGstRateRepository.getStateTaxRate(itemIds, stateId);
1758
        } else {
1759
            gstRates = stateGstRateRepository.getIgstTaxRate(itemIds);
1760
        }
1761
        for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
1762
            GstRate rate = gstRates.get(fofoOrderItem.getItemId());
1763
            fofoOrderItem.setCgstRate(rate.getCgstRate());
1764
            fofoOrderItem.setSgstRate(rate.getSgstRate());
1765
            fofoOrderItem.setIgstRate(rate.getIgstRate());
1766
        }
1767
    }
24275 amit.gupta 1768
 
32145 tejbeer 1769
    @Override
1770
    public CustomerCreditNote badReturn(int fofoId, FoiBadReturnRequest foiBadReturnRequest) throws ProfitMandiBusinessException {
1771
        FofoOrderItem foi = fofoOrderItemRepository.selectById(foiBadReturnRequest.getFofoOrderItemId());
1772
        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(foi.getOrderId());
1773
        if (fofoOrder.getFofoId() != fofoId) {
1774
            throw new ProfitMandiBusinessException("Partner Auth", "", "Invalid Order");
1775
        }
1776
        int billedQty = foi.getQuantity() - customerReturnItemRepository.selectAllByOrderItemId(foi.getId()).size();
1777
        if (foiBadReturnRequest.getMarkedBadArr().size() > billedQty) {
1778
            throw new ProfitMandiBusinessException("Cant bad return more than what is billed", "", "Invalid Quantity");
1779
        }
1780
        List<CustomerReturnItem> customerReturnItems = new ArrayList<>();
1781
        for (BadReturnRequest badReturnRequest : foiBadReturnRequest.getMarkedBadArr()) {
1782
            CustomerReturnItem customerReturnItem = new CustomerReturnItem();
1783
            customerReturnItem.setFofoId(fofoId);
1784
            customerReturnItem.setFofoOrderItemId(foiBadReturnRequest.getFofoOrderItemId());
1785
            customerReturnItem.setFofoOrderId(fofoOrder.getId());
1786
            customerReturnItem.setRemarks(badReturnRequest.getRemarks());
1787
            customerReturnItem.setInventoryItemId(badReturnRequest.getInventoryItemId());
1788
            customerReturnItem.setQuantity(1);
1789
            customerReturnItem.setType(ReturnType.BAD);
1790
            // customerReturnItemRepository.persist(customerReturnItem);
1791
            inventoryService.saleReturnInventoryItem(customerReturnItem);
1792
            customerReturnItems.add(customerReturnItem);
1793
        }
1794
        CustomerCreditNote creditNote = generateCreditNote(fofoOrder, customerReturnItems);
1795
        for (CustomerReturnItem customerReturnItem : customerReturnItems) {
1796
            purchaseReturnService.returnInventoryItem(fofoId, false, customerReturnItem.getInventoryItemId(), ReturnType.BAD);
1797
        }
1798
        // This should cancel the order
1799
        fofoOrder.setCancelledTimestamp(LocalDateTime.now());
1800
        this.reverseScheme(fofoOrder);
1801
        return creditNote;
1802
    }
23638 amit.gupta 1803
 
32145 tejbeer 1804
    private CustomerCreditNote generateCreditNote(FofoOrder fofoOrder, List<CustomerReturnItem> customerReturnItems) throws ProfitMandiBusinessException {
24275 amit.gupta 1805
 
32145 tejbeer 1806
        InvoiceNumberGenerationSequence sequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoOrder.getFofoId());
1807
        sequence.setCreditNoteSequence(sequence.getCreditNoteSequence() + 1);
1808
        invoiceNumberGenerationSequenceRepository.persist(sequence);
24275 amit.gupta 1809
 
32145 tejbeer 1810
        String creditNoteNumber = sequence.getPrefix() + "/" + sequence.getCreditNoteSequence();
1811
        CustomerCreditNote creditNote = new CustomerCreditNote();
1812
        creditNote.setCreditNoteNumber(creditNoteNumber);
1813
        creditNote.setFofoId(fofoOrder.getFofoId());
1814
        creditNote.setFofoOrderId(fofoOrder.getId());
1815
        creditNote.setFofoOrderItemId(customerReturnItems.get(0).getFofoOrderItemId());
1816
        creditNote.setSettlementType(SettlementType.UNSETTLED);
1817
        customerCreditNoteRepository.persist(creditNote);
24275 amit.gupta 1818
 
32145 tejbeer 1819
        for (CustomerReturnItem customerReturnItem : customerReturnItems) {
1820
            customerReturnItem.setCreditNoteId(creditNote.getId());
1821
            customerReturnItemRepository.persist(customerReturnItem);
1822
        }
1823
        // this.returnInventoryItems(inventoryItems, debitNote);
23655 amit.gupta 1824
 
32145 tejbeer 1825
        return creditNote;
1826
    }
23655 amit.gupta 1827
 
32145 tejbeer 1828
    @Override
1829
    public CreditNotePdfModel getCreditNotePdfModel(int customerCreditNoteId) throws ProfitMandiBusinessException {
1830
        CustomerCreditNote creditNote = customerCreditNoteRepository.selectById(customerCreditNoteId);
1831
        return getCreditNotePdfModel(creditNote);
1832
    }
24275 amit.gupta 1833
 
32145 tejbeer 1834
    private CreditNotePdfModel getCreditNotePdfModel(CustomerCreditNote creditNote) throws ProfitMandiBusinessException {
1835
        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(creditNote.getFofoOrderId());
1836
        List<CustomerReturnItem> customerReturnItems = customerReturnItemRepository.selectAllByCreditNoteId(creditNote.getId());
1837
        CustomCustomer customCustomer = getCustomCustomer(fofoOrder);
24275 amit.gupta 1838
 
32145 tejbeer 1839
        Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();
1840
        CustomRetailer customRetailer = retailerService.getFofoRetailer(fofoOrder.getFofoId());
23655 amit.gupta 1841
 
32145 tejbeer 1842
        FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(creditNote.getFofoOrderItemId());
1843
        float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
1844
        float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
1845
        float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
24275 amit.gupta 1846
 
32145 tejbeer 1847
        CustomOrderItem customFofoOrderItem = new CustomOrderItem();
1848
        customFofoOrderItem.setAmount(customerReturnItems.size() * (taxableSellingPrice - taxableDiscountPrice));
1849
        customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
24275 amit.gupta 1850
 
32145 tejbeer 1851
        if (ItemType.SERIALIZED.equals(itemRepository.selectById(fofoOrderItem.getItemId()).getType())) {
1852
            Set<Integer> inventoryItemIds = customerReturnItems.stream().map(x -> x.getInventoryItemId()).collect(Collectors.toSet());
1853
            List<String> serialNumbers = inventoryItemRepository.selectByIds(inventoryItemIds).stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());
1854
            customFofoOrderItem.setDescription(
1855
                    customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
1856
        }
23638 amit.gupta 1857
 
32145 tejbeer 1858
        customFofoOrderItem.setRate(taxableSellingPrice);
1859
        customFofoOrderItem.setDiscount(taxableDiscountPrice);
1860
        customFofoOrderItem.setQuantity(customerReturnItems.size());
1861
        customFofoOrderItem.setNetAmount(
1862
                (fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * customFofoOrderItem.getQuantity());
29707 tejbeer 1863
 
32145 tejbeer 1864
        float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
1865
        float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
1866
        float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
1867
        LOGGER.info("fofoOrderItem - {}", fofoOrderItem);
1868
        customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
1869
        customFofoOrderItem.setIgstAmount(igstAmount);
1870
        customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
1871
        customFofoOrderItem.setCgstAmount(cgstAmount);
1872
        customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
1873
        customFofoOrderItem.setSgstAmount(sgstAmount);
1874
        customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
1875
        customFofoOrderItem.setOrderId(1);
1876
        customerFofoOrderItems.add(customFofoOrderItem);
29707 tejbeer 1877
 
32145 tejbeer 1878
        InvoicePdfModel pdfModel = new InvoicePdfModel();
1879
        pdfModel.setAuther("NSSPL");
1880
        pdfModel.setCustomer(customCustomer);
1881
        pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
1882
        pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));
1883
        pdfModel.setTitle("Credit Note");
1884
        pdfModel.setRetailer(customRetailer);
1885
        pdfModel.setTotalAmount(customFofoOrderItem.getNetAmount());
1886
        pdfModel.setOrderItems(customerFofoOrderItems);
29707 tejbeer 1887
 
32145 tejbeer 1888
        CreditNotePdfModel creditNotePdfModel = new CreditNotePdfModel();
1889
        creditNotePdfModel.setCreditNoteDate(FormattingUtils.formatDate(creditNote.getCreateTimestamp()));
1890
        creditNotePdfModel.setCreditNoteNumber(creditNote.getCreditNoteNumber());
1891
        creditNotePdfModel.setPdfModel(pdfModel);
1892
        return creditNotePdfModel;
1893
    }
24264 amit.gupta 1894
 
32145 tejbeer 1895
    // This will remove the order and maintain order record and reverse inventory
1896
    // and scheme
1897
    @Override
1898
    public void cancelOrder(List<String> invoiceNumbers) throws ProfitMandiBusinessException {
1899
        for (String invoiceNumber : invoiceNumbers) {
1900
            // Cancel only when not cancelled
1901
            FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
1902
            if (fofoOrder.getCancelledTimestamp() == null) {
1903
                fofoOrder.setCancelledTimestamp(LocalDateTime.now());
1904
                PaymentOptionTransaction paymentTransaction = new PaymentOptionTransaction();
1905
                paymentTransaction.setAmount(-fofoOrder.getTotalAmount());
1906
                paymentTransaction.setFofoId(fofoOrder.getFofoId());
1907
                paymentTransaction.setReferenceId(fofoOrder.getId());
1908
                paymentTransaction.setReferenceType(PaymentOptionReferenceType.ORDER);
1909
                paymentTransaction.setPaymentOptionId(1);
1910
                paymentOptionTransactionRepository.persist(paymentTransaction);
31030 amit.gupta 1911
 
32145 tejbeer 1912
                List<FofoOrderItem> fois = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
1913
                if (fois.size() > 0) {
1914
                    List<InventoryItem> inventoryItems = new ArrayList<>();
1915
                    fois.stream().forEach(x -> {
1916
                        x.getFofoLineItems().stream().forEach(y -> {
1917
                            inventoryService.rollbackInventory(y.getInventoryItemId(), y.getQuantity(), fofoOrder.getFofoId());
1918
                            inventoryItems.add(inventoryItemRepository.selectById(y.getInventoryItemId()));
1919
                        });
1920
                    });
1921
                    // if(invoice)
1922
                    this.reverseScheme(fofoOrder);
1923
                }
1924
                insuranceService.cancelInsurance(fofoOrder);
1925
            }
1926
        }
1927
    }
31030 amit.gupta 1928
 
32145 tejbeer 1929
    @Override
1930
    public void reverseScheme(FofoOrder fofoOrder) throws ProfitMandiBusinessException {
1931
        String reversalReason = "Order Rolledback/Cancelled/Returned for Invoice #" + fofoOrder.getInvoiceNumber();
1932
        List<FofoOrderItem> fois = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
1933
        Set<Integer> inventoryItemIds = fois.stream().flatMap(x -> x.getFofoLineItems().stream().map(y -> y.getInventoryItemId())).collect(Collectors.toSet());
1934
        List<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIds);
1935
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, SchemeService.OUT_SCHEME_TYPES);
1936
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.INVESTMENT));
1937
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.ACTIVATION));
1938
        schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.SPECIAL_SUPPORT));
31030 amit.gupta 1939
 
32145 tejbeer 1940
    }
24271 amit.gupta 1941
 
32145 tejbeer 1942
    @Override
1943
    public void reverseActivationScheme(List<Integer> inventoryItemIds) throws ProfitMandiBusinessException {
1944
        List<InventoryItem> inventoryItems = inventoryItemRepository.selectAllByIds(inventoryItemIds);
1945
        for (InventoryItem inventoryItem : inventoryItems) {
1946
            List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByInventoryItemId(inventoryItem.getId());
1947
            FofoLineItem fofoLineItem = fofoLineItems.get(0);
1948
            FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(fofoLineItem.getFofoOrderItemId());
1949
            FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(fofoOrderItem.getOrderId());
1950
            String reversalReason = "Scheme rolled back as activation date is invalid for imei " + inventoryItem.getSerialNumber();
1951
            schemeService.reverseSchemes(Arrays.asList(inventoryItem), fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.ACTIVATION));
1952
            schemeService.reverseSchemes(Arrays.asList(inventoryItem), fofoOrder.getId(), reversalReason, Arrays.asList(SchemeType.SPECIAL_SUPPORT));
27083 amit.gupta 1953
 
32145 tejbeer 1954
        }
24271 amit.gupta 1955
 
32145 tejbeer 1956
    }
24271 amit.gupta 1957
 
32145 tejbeer 1958
    @Override
1959
    public float getSales(int fofoId, LocalDateTime startDate, LocalDateTime endDate) {
1960
        Float sales = fofoOrderRepository.selectSaleSumGroupByFofoIds(startDate, endDate).get(fofoId);
1961
        return sales == null ? 0f : sales;
1962
    }
24271 amit.gupta 1963
 
32145 tejbeer 1964
    @Override
1965
    public LocalDateTime getMaxSalesDate(int fofoId, LocalDateTime startDate, LocalDateTime endDate) {
1966
        LocalDateTime dateTime = fofoOrderRepository.selectMaxSaleDateGroupByFofoIds(startDate, endDate).get(fofoId);
1967
        return dateTime;
1968
    }
25101 amit.gupta 1969
 
32145 tejbeer 1970
    @Override
1971
    // Only being used internally
1972
    public float getSales(int fofoId, LocalDate onDate) {
1973
        LocalDateTime startTime = LocalDateTime.of(onDate, LocalTime.MIDNIGHT);
1974
        LocalDateTime endTime = LocalDateTime.of(onDate, LocalTime.MIDNIGHT).plusDays(1);
1975
        return this.getSales(fofoId, startTime, endTime);
1976
    }
24917 tejbeer 1977
 
32145 tejbeer 1978
    @Override
1979
    public float getSales(LocalDateTime onDate) {
1980
        // TODO Auto-generated method stub
1981
        return 0;
1982
    }
28166 tejbeer 1983
 
32145 tejbeer 1984
    @Override
1985
    public float getSales(LocalDateTime startDate, LocalDateTime endDate) {
1986
        // TODO Auto-generated method stub
1987
        return 0;
1988
    }
28166 tejbeer 1989
 
32145 tejbeer 1990
    @Override
1991
    public boolean notifyColorChange(int orderId, int itemId) throws ProfitMandiBusinessException {
1992
        Order order = orderRepository.selectById(orderId);
1993
        saholicInventoryService.reservationCountByColor(itemId, order);
28166 tejbeer 1994
 
32145 tejbeer 1995
        order.getLineItem().setItemId(itemId);
1996
        Item item = itemRepository.selectById(itemId);
1997
        order.getLineItem().setColor(item.getColor());
1998
        return true;
1999
    }
28166 tejbeer 2000
 
32145 tejbeer 2001
    @Override
2002
    public FofoOrder getOrderByInventoryItemId(int inventoryItemId) throws Exception {
2003
        List<FofoLineItem> lineItems = fofoLineItemRepository.selectByInventoryItemId(inventoryItemId);
2004
        if (lineItems.size() > 0) {
2005
            FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(lineItems.get(0).getFofoOrderItemId());
2006
            fofoOrderItem.setFofoLineItems(new HashSet<>(lineItems));
2007
            FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(fofoOrderItem.getOrderId());
2008
            fofoOrder.setOrderItem(fofoOrderItem);
2009
            return fofoOrder;
2010
        } else {
2011
            throw new Exception(String.format("Could not find inventoryItemId - %s", inventoryItemId));
2012
        }
2013
    }
28166 tejbeer 2014
 
32145 tejbeer 2015
    @Override
2016
    public Map<Integer, Long> carryBagCreditCount(int fofoId) throws ProfitMandiBusinessException {
28166 tejbeer 2017
 
32145 tejbeer 2018
        FofoStore fs = fofoStoreRepository.selectByRetailerId(fofoId);
2019
        LocalDateTime lastCredit = fs.getBagsLastCredited();
2020
        /*
2021
         * long carryBagCount = 0; List<FofoOrder> fofoOrders =
2022
         * fofoOrderRepository.selectByFofoIdBetweenCreatedTimeStamp(fofoId,
2023
         * lastCredit.atStartOfDay(), LocalDate.now().plusDays(1).atStartOfDay()); for
2024
         * (FofoOrder fo : fofoOrders) { carryBagCount +=
2025
         * fofoOrderItemRepository.selectByOrderId(fo.getId()).stream() .filter(x ->
2026
         * x.getSellingPrice() >= 12000).count();
2027
         *
2028
         * }
2029
         */
28166 tejbeer 2030
 
32145 tejbeer 2031
        Session session = sessionFactory.getCurrentSession();
2032
        CriteriaBuilder cb = session.getCriteriaBuilder();
2033
 
2034
        CriteriaQuery<SimpleEntry> query = cb.createQuery(SimpleEntry.class);
2035
        Root<FofoOrder> fofoOrder = query.from(FofoOrder.class);
2036
        Root<FofoOrderItem> fofoOrderItem = query.from(FofoOrderItem.class);
2037
        Root<TagListing> tagListingRoot = query.from(TagListing.class);
2038
        Root<Item> itemRoot = query.from(Item.class);
2039
 
2040
        Predicate p2 = cb.between(fofoOrder.get(ProfitMandiConstants.CREATE_TIMESTAMP), lastCredit, LocalDate.now().atStartOfDay());
2041
        Predicate p3 = cb.isNull(fofoOrder.get("cancelledTimestamp"));
2042
        Predicate joinPredicate = cb.and(
2043
                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));
2044
        ItemCriteria itemCriteria = new ItemCriteria();
2045
        itemCriteria.setBrands(mongoClient.getMongoBrands(fofoId, null, 3).stream().map(x -> (String) x.get("name")).collect(Collectors.toList()));
2046
        float startValue = 12000;
2047
        itemCriteria.setStartPrice(startValue);
2048
        itemCriteria.setEndPrice(0);
2049
        itemCriteria.setFeaturedPhone(false);
2050
        itemCriteria.setSmartPhone(true);
2051
        itemCriteria.setCatalogIds(new ArrayList<>());
2052
        itemCriteria.setExcludeCatalogIds(new ArrayList<>());
2053
        Predicate itemPredicate = itemRepository.getItemPredicate(itemCriteria, cb, itemRoot, tagListingRoot.get("itemId"), tagListingRoot.get("sellingPrice"));
2054
        Predicate finalPredicate = cb.and(itemPredicate, p2, p3, joinPredicate);
2055
        query = query.multiselect(fofoOrder.get(ProfitMandiConstants.FOFO_ID), cb.count(fofoOrder)).where(finalPredicate).groupBy(fofoOrder.get(ProfitMandiConstants.FOFO_ID));
2056
        List<SimpleEntry> simpleEntries = session.createQuery(query).getResultList();
2057
        Map<Integer, Long> returnMap = new HashMap<>();
2058
 
2059
        for (SimpleEntry simpleEntry : simpleEntries) {
2060
            returnMap.put((Integer) simpleEntry.getKey(), (Long) simpleEntry.getValue());
2061
        }
2062
        return returnMap;
2063
 
2064
    }
25724 amit.gupta 2065
}