Subversion Repositories SmartDukaan

Rev

Rev 23433 | Rev 23552 | 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
 
23418 ashik.ali 3
import java.io.IOException;
4
import java.net.URISyntaxException;
22859 ashik.ali 5
import java.time.DateTimeException;
6
import java.time.LocalDate;
23202 ashik.ali 7
import java.time.LocalDateTime;
22859 ashik.ali 8
import java.util.ArrayList;
9
import java.util.HashMap;
10
import java.util.HashSet;
11
import java.util.Iterator;
12
import java.util.List;
13
import java.util.Map;
23418 ashik.ali 14
import java.util.Random;
22859 ashik.ali 15
import java.util.Set;
22955 ashik.ali 16
import java.util.function.Function;
17
import java.util.stream.Collectors;
22859 ashik.ali 18
 
19
import org.json.JSONObject;
20
import org.slf4j.Logger;
21
import org.slf4j.LoggerFactory;
22
import org.springframework.beans.factory.annotation.Autowired;
23
import org.springframework.stereotype.Component;
24
 
23418 ashik.ali 25
import com.spice.profitmandi.common.ResponseCodeHolder;
23202 ashik.ali 26
import com.spice.profitmandi.common.enumuration.SearchType;
22859 ashik.ali 27
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
28
import com.spice.profitmandi.common.model.CartFofo;
29
import com.spice.profitmandi.common.model.CreateOrderRequest;
30
import com.spice.profitmandi.common.model.CustomAddress;
31
import com.spice.profitmandi.common.model.CustomCustomer;
32
import com.spice.profitmandi.common.model.CustomFofoOrderItem;
33
import com.spice.profitmandi.common.model.CustomInsurancePolicy;
34
import com.spice.profitmandi.common.model.CustomOrderItem;
35
import com.spice.profitmandi.common.model.CustomPaymentOption;
36
import com.spice.profitmandi.common.model.CustomRetailer;
37
import com.spice.profitmandi.common.model.GadgetCopsInsuranceModel;
23172 ashik.ali 38
import com.spice.profitmandi.common.model.GstRate;
22859 ashik.ali 39
import com.spice.profitmandi.common.model.ItemIdQuantityAvailability;
40
import com.spice.profitmandi.common.model.PdfModel;
41
import com.spice.profitmandi.common.model.PriceModel;
42
import com.spice.profitmandi.common.model.ProfitMandiConstants;
43
import com.spice.profitmandi.common.model.Quantity;
44
import com.spice.profitmandi.common.model.SerialNumberDetail;
45
import com.spice.profitmandi.common.util.InsuranceUtils;
46
import com.spice.profitmandi.common.util.StringUtils;
23172 ashik.ali 47
import com.spice.profitmandi.common.util.Utils;
22859 ashik.ali 48
import com.spice.profitmandi.dao.entity.catalog.Item;
49
import com.spice.profitmandi.dao.entity.dtr.GadgetCopsInsuranceCalc;
50
import com.spice.profitmandi.dao.entity.dtr.InsurancePolicy;
51
import com.spice.profitmandi.dao.entity.dtr.InsuranceProvider;
23418 ashik.ali 52
import com.spice.profitmandi.dao.entity.dtr.Otp;
23546 ashik.ali 53
import com.spice.profitmandi.dao.entity.dtr.PaymentOptionTransaction;
22859 ashik.ali 54
import com.spice.profitmandi.dao.entity.dtr.PolicyNumberGenerationSequence;
55
import com.spice.profitmandi.dao.entity.dtr.Retailer;
56
import com.spice.profitmandi.dao.entity.dtr.User;
57
import com.spice.profitmandi.dao.entity.fofo.CurrentInventorySnapshot;
58
import com.spice.profitmandi.dao.entity.fofo.Customer;
59
import com.spice.profitmandi.dao.entity.fofo.CustomerAddress;
60
import com.spice.profitmandi.dao.entity.fofo.FofoLineItem;
61
import com.spice.profitmandi.dao.entity.fofo.FofoOrder;
62
import com.spice.profitmandi.dao.entity.fofo.FofoOrderItem;
23202 ashik.ali 63
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
22859 ashik.ali 64
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
65
import com.spice.profitmandi.dao.entity.fofo.InvoiceNumberGenerationSequence;
23418 ashik.ali 66
import com.spice.profitmandi.dao.entity.fofo.PrebookingListing;
67
import com.spice.profitmandi.dao.entity.fofo.PrebookingOrder;
68
import com.spice.profitmandi.dao.entity.fofo.PrebookingOrderItem;
22859 ashik.ali 69
import com.spice.profitmandi.dao.entity.fofo.ScanRecord;
70
import com.spice.profitmandi.dao.entity.user.Address;
71
import com.spice.profitmandi.dao.entity.user.Counter;
72
import com.spice.profitmandi.dao.entity.user.PrivateDealUser;
23418 ashik.ali 73
import com.spice.profitmandi.dao.enumuration.dtr.OtpType;
23546 ashik.ali 74
import com.spice.profitmandi.dao.enumuration.dtr.PaymentOptionReferenceType;
22859 ashik.ali 75
import com.spice.profitmandi.dao.enumuration.fofo.ScanType;
76
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
23546 ashik.ali 77
import com.spice.profitmandi.dao.repository.dtr.PaymentOptionTransactionRepository;
23202 ashik.ali 78
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
22859 ashik.ali 79
import com.spice.profitmandi.dao.repository.dtr.InsurancePolicyRepository;
80
import com.spice.profitmandi.dao.repository.dtr.InsuranceProviderRepository;
23418 ashik.ali 81
import com.spice.profitmandi.dao.repository.dtr.OtpRepository;
22859 ashik.ali 82
import com.spice.profitmandi.dao.repository.dtr.PolicyNumberGenerationSequenceRepository;
83
import com.spice.profitmandi.dao.repository.dtr.RetailerRegisteredAddressRepository;
84
import com.spice.profitmandi.dao.repository.dtr.RetailerRepository;
85
import com.spice.profitmandi.dao.repository.dtr.UserAccountRepository;
86
import com.spice.profitmandi.dao.repository.dtr.UserRepository;
87
import com.spice.profitmandi.dao.repository.fofo.CurrentInventorySnapshotRepository;
88
import com.spice.profitmandi.dao.repository.fofo.CustomerAddressRepository;
89
import com.spice.profitmandi.dao.repository.fofo.CustomerRepository;
90
import com.spice.profitmandi.dao.repository.fofo.FofoLineItemRepository;
91
import com.spice.profitmandi.dao.repository.fofo.FofoOrderItemRepository;
92
import com.spice.profitmandi.dao.repository.fofo.FofoOrderRepository;
93
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
94
import com.spice.profitmandi.dao.repository.fofo.InvoiceNumberGenerationSequenceRepository;
95
import com.spice.profitmandi.dao.repository.fofo.PaymentOptionRepository;
23418 ashik.ali 96
import com.spice.profitmandi.dao.repository.fofo.PrebookingListingRepository;
97
import com.spice.profitmandi.dao.repository.fofo.PrebookingOrderItemRepository;
98
import com.spice.profitmandi.dao.repository.fofo.PrebookingOrderRepository;
22859 ashik.ali 99
import com.spice.profitmandi.dao.repository.fofo.ScanRecordRepository;
100
import com.spice.profitmandi.dao.repository.user.AddressRepository;
101
import com.spice.profitmandi.dao.repository.user.CounterRepository;
102
import com.spice.profitmandi.dao.repository.user.PrivateDealUserRepository;
23418 ashik.ali 103
import com.spice.profitmandi.service.inventory.InventoryService;
22859 ashik.ali 104
import com.spice.profitmandi.service.pricing.PricingService;
105
import com.spice.profitmandi.service.scheme.SchemeService;
23395 amit.gupta 106
import com.spice.profitmandi.service.wallet.WalletService;
22859 ashik.ali 107
 
108
import in.shop2020.model.v1.catalog.ItemType;
23395 amit.gupta 109
import in.shop2020.model.v1.order.WalletReferenceType;
22859 ashik.ali 110
 
111
@Component
112
public class OrderServiceImpl implements OrderService {
113
 
114
	private static final Logger LOGGER = LoggerFactory.getLogger(OrderServiceImpl.class);
115
 
116
	@Autowired
117
	private InventoryItemRepository inventoryItemRepository;
23395 amit.gupta 118
 
119
	@Autowired
120
	private WalletService walletService;
22859 ashik.ali 121
 
122
	@Autowired
123
	private CurrentInventorySnapshotRepository currentInventorySnapshotRepository;
124
 
125
	@Autowired
126
	private InvoiceNumberGenerationSequenceRepository invoiceNumberGenerationSequenceRepository;
127
 
128
	@Autowired
129
	private CustomerRepository customerRepository;
130
 
131
	@Autowired
132
	private AddressRepository addressRepository;
133
 
134
	@Autowired
135
	private FofoLineItemRepository fofoLineItemRepository;
136
 
137
	@Autowired
138
	private FofoOrderItemRepository fofoOrderItemRepository;
139
 
140
	@Autowired
141
	private PaymentOptionRepository paymentOptionRepository;
142
 
143
	@Autowired
144
	private ScanRecordRepository scanRecordRepository;
145
 
146
	@Autowired
147
	private FofoOrderRepository fofoOrderRepository;
148
 
149
	@Autowired
150
	private RetailerRepository retailerRepository;
151
 
152
	@Autowired
153
	private UserRepository userRepository;
154
 
155
	@Autowired
156
	private UserAccountRepository userAccountRepository;
157
 
158
	@Autowired
159
	private RetailerRegisteredAddressRepository retailerRegisteredAddressRepository;
160
 
161
	@Autowired
162
	private CustomerAddressRepository customerAddressRepository;
163
 
164
	@Autowired
165
	private ItemRepository itemRepository;
166
 
167
	@Autowired
168
	private InsuranceProviderRepository insuranceProviderRepository;
169
 
170
	@Autowired
171
	private InsurancePolicyRepository insurancePolicyRepository;
172
 
173
	@Autowired
174
	private PolicyNumberGenerationSequenceRepository policyNumberGenerationSequenceRepository;
175
 
176
	@Autowired
177
	private PricingService pricingService;
178
 
179
	@Autowired
180
	private PrivateDealUserRepository privateDealUserRepository;
181
 
182
	@Autowired
183
	private CounterRepository counterRepository;
184
 
185
	@Autowired
23202 ashik.ali 186
	private FofoStoreRepository fofoStoreRepository;
187
 
188
	@Autowired
23546 ashik.ali 189
	private PaymentOptionTransactionRepository paymentOptionTransactionRepository;
23365 ashik.ali 190
 
191
	@Autowired
23418 ashik.ali 192
	private PrebookingListingRepository prebookingListingRepository;
193
 
194
	@Autowired
195
	private PrebookingOrderRepository prebookingOrderRepository;
196
 
197
	@Autowired
198
	private PrebookingOrderItemRepository prebookingOrderItemRepository;
199
 
200
	@Autowired
22859 ashik.ali 201
	private SchemeService schemeService;
202
 
23418 ashik.ali 203
	@Autowired
204
	private InventoryService inventoryService;
205
 
206
	@Autowired
207
	private OtpRepository otpRepository;
208
 
22859 ashik.ali 209
	@Override
210
	public int createOrder(CreateOrderRequest createOrderRequest, int fofoId) throws ProfitMandiBusinessException {
211
 
22872 ashik.ali 212
		CustomCustomer customCustomer = createOrderRequest.getCustomer();
213
 
214
		if(!StringUtils.isValidEmailAddress(customCustomer.getEmailId())){
215
			LOGGER.error("invalid customer emailId {} ", customCustomer.getEmailId());
22925 ashik.ali 216
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EMAIL_ID, customCustomer.getEmailId(), "VE_1016");
22872 ashik.ali 217
		}
218
 
219
		if(!StringUtils.isValidMobile(customCustomer.getMobileNumber())){
220
			LOGGER.error("invalid customer mobileNumber {} ", customCustomer.getMobileNumber());
22925 ashik.ali 221
			throw new ProfitMandiBusinessException(ProfitMandiConstants.MOBILE_NUMBER, customCustomer.getMobileNumber(), "VE_1071");
22872 ashik.ali 222
		}
223
 
23370 ashik.ali 224
		if(!StringUtils.isValidGstNumber(customCustomer.getGstNumber())) {
23369 ashik.ali 225
			LOGGER.error("invalid customer gstNumber {} ", customCustomer.getGstNumber());
226
			throw new ProfitMandiBusinessException(ProfitMandiConstants.CUSTOMER_GST_NUMBER, customCustomer.getGstNumber(), "VE_1072");
227
		}
228
 
22859 ashik.ali 229
		Map<Integer, Integer> itemIdQuantity = new HashMap<>(); //this is for error
22872 ashik.ali 230
		Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap = new HashMap<>();
22859 ashik.ali 231
		Map<Integer, Float> lineItemPrice = new HashMap<>(); //this is for pricing error
232
 
23418 ashik.ali 233
		Map<Integer, Integer> prebookingOrderItemIdQuantityMap = new HashMap<>(); // for prebooking order adjustment
23377 ashik.ali 234
 
22859 ashik.ali 235
		float totalAmount = 0;
236
		for(CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()){
22872 ashik.ali 237
			//itemIds.add(customFofoOrderItem.getItemId());
23418 ashik.ali 238
			if(customFofoOrderItem.isPrebookingOrder()) {
239
				prebookingOrderItemIdQuantityMap.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
240
			}
23377 ashik.ali 241
			Set<String> serialNumbers = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());
242
			if(!serialNumbers.isEmpty() && customFofoOrderItem.getQuantity() != serialNumbers.size()){
22859 ashik.ali 243
				itemIdQuantity.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
244
			}
245
			if(!(customFofoOrderItem.getSellingPrice() > 0)){
246
				lineItemPrice.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getSellingPrice());
247
			}else{
22863 ashik.ali 248
				totalAmount = totalAmount + customFofoOrderItem.getSellingPrice() * customFofoOrderItem.getQuantity();
249
				totalAmount = totalAmount - customFofoOrderItem.getDiscountAmount() * customFofoOrderItem.getQuantity();
22859 ashik.ali 250
				for(SerialNumberDetail serialNumberDetail : customFofoOrderItem.getSerialNumberDetails()){
251
					if(serialNumberDetail.isInsurance() && serialNumberDetail.getAmount() > 0){
252
						totalAmount = totalAmount + serialNumberDetail.getAmount();
253
					}
254
				}
255
			}
256
 
22872 ashik.ali 257
			itemIdCustomFofoOrderItemMap.put(customFofoOrderItem.getItemId(), customFofoOrderItem);
22859 ashik.ali 258
		}
259
		if(!itemIdQuantity.isEmpty()){
260
			// if item quantity does not match with given serialnumbers size
261
			LOGGER.error("itemId's quantity should be equal to given serialnumber size {} ", itemIdQuantity);
22925 ashik.ali 262
			throw new ProfitMandiBusinessException("itemIdQuantity", itemIdQuantity, "FFORDR_1001");
22859 ashik.ali 263
			//return "error";
264
		}
265
 
23427 amit.gupta 266
		List<PrebookingListing> prebookingListings = new ArrayList<>();
267
		Map<Integer, PrebookingListing> itemIdPrebookingListingMap  = new HashMap<>();
268
		List<PrebookingOrder> prebookingOrders = new ArrayList<>();
269
		float prebookingOrdersTotalAmount = 0;
270
		if(!prebookingOrderItemIdQuantityMap.isEmpty()) {
271
			prebookingListings = prebookingListingRepository.selectAllByItemIds(prebookingOrderItemIdQuantityMap.keySet());
272
			itemIdPrebookingListingMap = this.prebookingListingsToItemIdPrebookingListingMap(prebookingListings);
273
			prebookingOrders = prebookingOrderRepository.selectByFofoIdCustomerMobileNumberItemIds(fofoId, customCustomer.getMobileNumber(), prebookingOrderItemIdQuantityMap.keySet());
274
			prebookingOrdersTotalAmount = this.calculatePrebookingOrdersAmount(prebookingOrders, prebookingOrderItemIdQuantityMap, itemIdPrebookingListingMap);
275
		}
22859 ashik.ali 276
 
23418 ashik.ali 277
		this.validatePaymentOptionsAndTotalAmount(createOrderRequest.getPaymentOptions(), totalAmount - prebookingOrdersTotalAmount);
278
 
22859 ashik.ali 279
		if(!lineItemPrice.isEmpty()){
280
			// given fofo line item price must be greater than zero
281
			LOGGER.error("requested itemId's selling price must greater than 0");
22925 ashik.ali 282
			throw new ProfitMandiBusinessException(ProfitMandiConstants.PRICE, lineItemPrice, "FFORDR_1002");
22859 ashik.ali 283
		}
284
 
22872 ashik.ali 285
		List<CurrentInventorySnapshot> currentInventorySnapshots = currentInventorySnapshotRepository.selectByFofoItemIds(fofoId, itemIdCustomFofoOrderItemMap.keySet());
22859 ashik.ali 286
 
22872 ashik.ali 287
		this.validateCurrentInventorySnapshotQuantities(currentInventorySnapshots, itemIdCustomFofoOrderItemMap);
22859 ashik.ali 288
 
289
 
22872 ashik.ali 290
		List<Item> items = itemRepository.selectByIds(itemIdCustomFofoOrderItemMap.keySet());
291
		if(items.size() != itemIdCustomFofoOrderItemMap.keySet().size()){
292
			LOGGER.error("Requested ItemIds not found in catalog");
293
			// invalid itemIds 
22925 ashik.ali 294
			throw new ProfitMandiBusinessException("invalidItemIds", itemIdCustomFofoOrderItemMap.keySet(), "FFORDR_1003");
22872 ashik.ali 295
		}
296
 
22859 ashik.ali 297
		Map<Integer, Item>  itemMap = this.toItemMap(items);
23418 ashik.ali 298
 
22859 ashik.ali 299
		Set<Integer> nonSerializedItemIds = new HashSet<>();
300
		Set<String> serialNumbers = new HashSet<>();
301
		Map<String, Float> insuranceSerialNumberItemPrice = new HashMap<>();
302
		Map<String, Float> insuranceSerialNumberSaleAmount = new HashMap<>();
303
		Map<String, String> serialNumberModelName = new HashMap<>();
304
		Map<String, String> serialNumberBrand = new HashMap<>();
22872 ashik.ali 305
		for (CustomFofoOrderItem customFofoOrderItem: createOrderRequest.getFofoOrderItems()){
306
			Item item = itemMap.get(customFofoOrderItem.getItemId());
22859 ashik.ali 307
			if (item.getType().equals(ItemType.SERIALIZED)){
22872 ashik.ali 308
				for (SerialNumberDetail serialNumberDetail : customFofoOrderItem.getSerialNumberDetails()){
22859 ashik.ali 309
					serialNumbers.add(serialNumberDetail.getSerialNumber());
310
					if(serialNumberDetail.isInsurance()){
22872 ashik.ali 311
						insuranceSerialNumberItemPrice.put(serialNumberDetail.getSerialNumber(), customFofoOrderItem.getSellingPrice());
22859 ashik.ali 312
						insuranceSerialNumberSaleAmount.put(serialNumberDetail.getSerialNumber(), serialNumberDetail.getAmount());
23393 amit.gupta 313
						serialNumberModelName.put(serialNumberDetail.getSerialNumber(), (item.getModelName() + item.getModelNumber()).trim());
22859 ashik.ali 314
						serialNumberBrand.put(serialNumberDetail.getSerialNumber(), item.getBrand());
315
					}
316
				}
317
			}
318
			else{
22872 ashik.ali 319
				nonSerializedItemIds.add(customFofoOrderItem.getItemId());
22859 ashik.ali 320
			}
321
		}
23418 ashik.ali 322
 
22859 ashik.ali 323
		Map<Integer, Set<InventoryItem>> serializedInventoryItemMap = new HashMap<>();
324
		Map<Integer, Set<InventoryItem>> nonSerializedInventoryItemMap = new HashMap<>();
23382 amit.gupta 325
		//Map<String, Float> serialNumberItemPrice = new HashMap<>();
23418 ashik.ali 326
 
23397 amit.gupta 327
		if (!serialNumbers.isEmpty()){
328
			List<InventoryItem> serializedInventoryItems = inventoryItemRepository.selectByFofoIdSerialNumbers(fofoId, serialNumbers);
329
			LOGGER.info("serializedInventoryItems {}", serializedInventoryItems);
330
			for (InventoryItem inventoryItem : serializedInventoryItems){
331
				if (inventoryItem.getGoodQuantity() == 1){
332
					if (serializedInventoryItemMap.containsKey(inventoryItem.getItemId())){
333
						serializedInventoryItemMap.get(inventoryItem.getItemId()).add(inventoryItem);
23418 ashik.ali 334
					}else{
23397 amit.gupta 335
						Set<InventoryItem> itemIdInventoryItems = new HashSet<>();
336
						itemIdInventoryItems.add(inventoryItem);
337
						serializedInventoryItemMap.put(inventoryItem.getItemId(), itemIdInventoryItems);
338
					}
339
				}
340
			}
341
		}
23418 ashik.ali 342
 
22859 ashik.ali 343
		if (!nonSerializedItemIds.isEmpty()){
344
			List<InventoryItem> nonSerializedInventoryItems = inventoryItemRepository.selectByFofoIdItemIds(fofoId, nonSerializedItemIds);
22872 ashik.ali 345
			LOGGER.info("nonSerializedInventoryItems {}", nonSerializedInventoryItems);
22859 ashik.ali 346
			for (InventoryItem it : nonSerializedInventoryItems){
347
				if (it.getGoodQuantity() > 0){
348
					if (nonSerializedInventoryItemMap.containsKey(it.getItemId())){
349
						nonSerializedInventoryItemMap.get(it.getItemId()).add(it);
23383 ashik.ali 350
					}else{
22859 ashik.ali 351
						Set<InventoryItem> tmp = new HashSet<>();
352
						tmp.add(it);
353
						nonSerializedInventoryItemMap.put(it.getItemId(), tmp);
354
					}
355
				}
356
			}
357
		}
358
 
22872 ashik.ali 359
		this.validateItemsSerializedNonSerialized(items, itemIdCustomFofoOrderItemMap);
22859 ashik.ali 360
 
361
		Map<Integer, Set<InventoryItem>> inventoryItemsToBill = new HashMap<>();
362
		Map<Integer, Integer> inventoryItemIdQuantityUsed = new HashMap<>(); //to keep track of inventoryitem quanity used for scan records insertion
363
 
364
		LOGGER.info("itemMap keys {}", itemMap.keySet());
365
		//Lets reduce quantity and decide what inventory items to use.
366
		for (Item item : items){
367
			if (item.getType().equals(ItemType.SERIALIZED)){
368
				//TODO:handle null
22872 ashik.ali 369
				if (serializedInventoryItemMap.get(item.getId()) == null || itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().size() != serializedInventoryItemMap.get(item.getId()).size()){
22859 ashik.ali 370
					//not enough serial numbers
371
					//LOGGER.info("serialNumbers {}", serialNumbers);
22872 ashik.ali 372
					//LOGGER.info("serializedInventoryItemMap {}", serializedInventoryItemMap);
373
					LOGGER.error("itemId {} => mismatch size of requested serial numbers", item.getId());
22955 ashik.ali 374
					Function<SerialNumberDetail, String> serialNumberDetailToSerialNumberFunction = new Function<SerialNumberDetail, String>() {
375
						@Override
376
						public String apply(SerialNumberDetail serialNumberDetail) {
377
							return serialNumberDetail.getSerialNumber();
378
						}
379
					};
380
					throw new ProfitMandiBusinessException("invalidSerialNumbers", itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().stream().map(serialNumberDetailToSerialNumberFunction).collect(Collectors.toList()), "FFORDR_1004");
22872 ashik.ali 381
				}
22859 ashik.ali 382
				Set<InventoryItem> inventoryItemsSerializedserialized = serializedInventoryItemMap.get(item.getId());
22872 ashik.ali 383
				for (InventoryItem inventoryItem : inventoryItemsSerializedserialized){
384
					inventoryItem.setGoodQuantity(0);
385
					inventoryItemIdQuantityUsed.put(inventoryItem.getId(), 1);
22859 ashik.ali 386
				}
387
				inventoryItemsToBill.put(item.getId(), inventoryItemsSerializedserialized);
388
			}
389
			else{
390
				Set<InventoryItem> inventoryItemsNonSerialized = nonSerializedInventoryItemMap.get(item.getId());
22872 ashik.ali 391
				int quantityToBill = itemIdCustomFofoOrderItemMap.get(item.getId()).getQuantity();
22859 ashik.ali 392
				int totalLeft = quantityToBill;
393
				Set<InventoryItem> inventoryItemsNonSerializedUsed = new HashSet<>();
394
				if (inventoryItemsNonSerialized!=null){
395
					for (InventoryItem inventoryItem : inventoryItemsNonSerialized){
396
						if (totalLeft > 0){
397
							int toUse = Math.min(totalLeft, inventoryItem.getGoodQuantity());
398
							inventoryItemIdQuantityUsed.put(inventoryItem.getId(), toUse);
399
							inventoryItem.setGoodQuantity(inventoryItem.getGoodQuantity()  - toUse);
400
							totalLeft = totalLeft - toUse;
401
							inventoryItemsNonSerializedUsed.add(inventoryItem);
402
						}
403
					}
404
				}
405
 
406
				if (totalLeft > 0){
407
					//not enough quanity for non-serialized
408
					LOGGER.error("not enough quanity for non-serialized");
22925 ashik.ali 409
					throw new ProfitMandiBusinessException("notEnoughQuantityForNonSerialized", totalLeft, "FFORDR_1005");
22859 ashik.ali 410
				}
411
				inventoryItemsToBill.put(item.getId(), inventoryItemsNonSerializedUsed);
412
			}
413
		}
414
 
22872 ashik.ali 415
		Map<Integer, PriceModel> itemIdMopPriceMap = pricingService.getPurchasePriceMopPriceNotFound(itemIdCustomFofoOrderItemMap.keySet(), fofoId);
22859 ashik.ali 416
 
22872 ashik.ali 417
		this.validateMopPrice(itemIdMopPriceMap, itemIdCustomFofoOrderItemMap);
23202 ashik.ali 418
 
419
		String fofoStoreCode = this.getFofoStoreCode(fofoId);
22859 ashik.ali 420
 
23202 ashik.ali 421
		InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = this.createAndGetInvoiceNumberGenerationSequence(fofoId, fofoStoreCode);
22859 ashik.ali 422
 
423
		Customer customer = this.createAndGetCustomer(customCustomer);
424
 
23191 ashik.ali 425
		CustomerAddress customerAddress = this.createCustomerAddress(customCustomer.getAddress(), customer.getId());
22859 ashik.ali 426
 
23433 ashik.ali 427
		FofoOrder fofoOrder = this.createAndGetFofoOrder(customer.getId(), customCustomer.getGstNumber(), fofoId, invoiceNumberGenerationSequence, totalAmount, customerAddress.getId());
22859 ashik.ali 428
 
429
		this.createPaymentOptions(fofoOrder.getId(), createOrderRequest.getPaymentOptions());
430
 
23433 ashik.ali 431
		this.processPrebookingOrders(fofoId, fofoOrder.getId(), prebookingOrders, prebookingOrderItemIdQuantityMap, itemIdPrebookingListingMap);
23418 ashik.ali 432
 
23172 ashik.ali 433
		int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoId);
434
 
435
		Address retailerAddress = addressRepository.selectById(retailerAddressId);
436
 
437
		Integer stateId = null;
438
		if(customerAddress.getState().equals(retailerAddress.getState())){
439
			try{
440
				stateId = Long.valueOf(Utils.getStateInfo(customerAddress.getState()).getId()).intValue();
441
			}catch(Exception e){
442
				LOGGER.error("Unable to get state rates");
443
			}
444
		}
445
 
22859 ashik.ali 446
		for(CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()){
23393 amit.gupta 447
			FofoOrderItem fofoOrderItem = this.createAndGetFofoOrderItem(customFofoOrderItem, fofoOrder.getId(), itemMap, inventoryItemsToBill.get(customFofoOrderItem.getItemId()), stateId);
22859 ashik.ali 448
 
449
			Set<InventoryItem> inventoryItems = inventoryItemsToBill.get(customFofoOrderItem.getItemId());
450
 
451
			this.createFofoLineItem(fofoOrderItem.getId(), inventoryItems, inventoryItemIdQuantityUsed);
452
 
453
			this.updateCurrentInventorySnapshot(currentInventorySnapshots, fofoId, customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
454
 
455
			this.updateInventoryItemsAndScanRecord(inventoryItems, fofoId, inventoryItemIdQuantityUsed);
456
		}
457
 
458
		// insurance calculation is insurance flag is enabled
459
		if(!insuranceSerialNumberItemPrice.isEmpty()){
460
			LOGGER.info("Processing for insurence for serialNumbers");
461
			Map<Float, GadgetCopsInsuranceCalc> insurancePricesMap = pricingService.getInsurancePrices(new HashSet<>(insuranceSerialNumberItemPrice.values()), ProfitMandiConstants.GADGET_COPS);
462
			InsuranceProvider insuranceProvider = insuranceProviderRepository.selectByName(ProfitMandiConstants.GADGET_COPS);
463
 
464
			this.validateInsuranceAmount(insuranceSerialNumberItemPrice, insuranceSerialNumberSaleAmount, insurancePricesMap);
465
 
22872 ashik.ali 466
			this.validateInsuranceMargin(insuranceSerialNumberItemPrice, itemIdCustomFofoOrderItemMap, itemIdMopPriceMap, insurancePricesMap, insuranceSerialNumberSaleAmount);
22859 ashik.ali 467
 
468
			LocalDate customerDateOfBirth = this.validateCustomerDateOfBirth(createOrderRequest.getCustomerDateOfBirth());
469
 
470
			for(Map.Entry<String, Float> entry : insuranceSerialNumberItemPrice.entrySet()){
471
				PolicyNumberGenerationSequence policyNumberGenerationSequence = this.createPolicyNumberGenerationSequence();
472
 
473
				InsurancePolicy insurancePolicy = this.createInsurancePolicy(
23394 amit.gupta 474
						fofoOrder.getInvoiceNumber(), fofoId,
22859 ashik.ali 475
						insurancePricesMap.get(entry.getValue()).getDealerPrice(),
476
						insuranceSerialNumberSaleAmount.get(entry.getKey()),entry.getValue(),
477
						entry.getKey(), serialNumberModelName.get(entry.getKey()),
478
						serialNumberBrand.get(entry.getKey()), policyNumberGenerationSequence.getSequence(),
479
						insuranceProvider.getId(), customer, customerDateOfBirth, customerAddress);
480
 
481
				GadgetCopsInsuranceModel gadgetCopsInsuranceModel = this.createGadgetCopsInsuranceModel(serialNumberBrand.get(entry.getKey()), serialNumberModelName.get(entry.getKey()), entry.getKey(), customerDateOfBirth, customer, customerAddress, insurancePolicy);
23395 amit.gupta 482
				String walletDescription = "Sale of " + insurancePolicy.getPolicyNumber() 
483
				+ " for " + fofoOrder.getInvoiceNumber();
484
				walletService.consumeAmountFromWallet(fofoId, insurancePolicy.getId(), 
485
						WalletReferenceType.DAMAGE_PROTECTION, walletDescription, insurancePolicy.getPurchaseAmount());
22859 ashik.ali 486
 
487
				try{
488
					InsuranceUtils.submitToGadgetCops(gadgetCopsInsuranceModel);
489
					insurancePolicy.setPosted(true);
490
				}catch (ProfitMandiBusinessException profitMandiBusinessException) {
491
					LOGGER.info("Unable to submit insurance policy details to {}", insuranceProvider.getName(), profitMandiBusinessException);
492
				}
493
				insurancePolicyRepository.persist(insurancePolicy);
494
			}
495
		}
23365 ashik.ali 496
		schemeService.processSchemeOut(fofoOrder.getId(), fofoId);
497
 
22859 ashik.ali 498
		return fofoOrder.getId();
499
	}
500
 
23418 ashik.ali 501
	private float calculatePrebookingOrdersAmount(List<PrebookingOrder> prebookingOrders, Map<Integer, Integer> prebookingOrderItemIdQuantityMap, Map<Integer, PrebookingListing> itemIdPrebookingListingMap) {
502
		//List<PrebookingOrder> prebookingOrders = prebookingOrderRepository.selectByFofoIdCustomerMobileNumberItemIds(fofoId, customerMobileNumber, prebookingOrderItemIdQuantityMap.keySet());
503
		float totalAmount = 0;
504
		for(PrebookingOrder prebookingOrder : prebookingOrders) {
505
			int requestedQuantity = prebookingOrderItemIdQuantityMap.get(prebookingOrder.getItemId());
506
			PrebookingListing prebookingListing = itemIdPrebookingListingMap.get(prebookingOrder.getItemId());
507
			if(requestedQuantity < prebookingOrder.getAvailableQuantity()) {
508
				LOGGER.info("when requestedQuantity < then requestedQuantity [{}] * advanceAmount [{}]", requestedQuantity, prebookingListing.getAdvanceAmount());
509
				totalAmount = totalAmount + (requestedQuantity * prebookingListing.getAdvanceAmount());
510
			}else if(requestedQuantity >= prebookingOrder.getAvailableQuantity()) {
511
				LOGGER.info("else requestedQuantity [{}] * advanceAmount [{}]", requestedQuantity, prebookingListing.getAdvanceAmount());
512
				totalAmount = totalAmount + (prebookingOrder.getAvailableQuantity() * prebookingListing.getAdvanceAmount());
513
			}
514
		}
515
		return totalAmount;
516
	}
517
 
23433 ashik.ali 518
	private void processPrebookingOrders(int fofoId, int orderId, List<PrebookingOrder> prebookingOrders, Map<Integer, Integer> prebookingOrderItemIdQuantityMap, Map<Integer, PrebookingListing> itemIdPrebookingListingMap) 
519
	throws ProfitMandiBusinessException{
23418 ashik.ali 520
		//Map<Integer, PrebookingOrder> prebookingOrderIdPrebookingOrderMap = this.prebookingOrdersToPrebookingOrderIdPrebookingOrderMap(prebookingOrders);
521
 
522
		for(PrebookingOrder prebookingOrder : prebookingOrders) {
523
			if(prebookingOrder.getCompleteTimestamp() == null) {
524
				int requestedQuantity = prebookingOrderItemIdQuantityMap.get(prebookingOrder.getItemId());
525
 
526
				PrebookingOrderItem prebookingOrderItem = new PrebookingOrderItem();
527
				if(requestedQuantity < prebookingOrder.getAvailableQuantity()) {
528
					prebookingOrder.setAvailableQuantity(prebookingOrder.getAvailableQuantity() - requestedQuantity);
529
					prebookingOrderItem.setQuantity(requestedQuantity);
530
				}else if(requestedQuantity >= prebookingOrder.getAvailableQuantity()) {
531
					prebookingOrderItem.setQuantity(prebookingOrder.getAvailableQuantity());
532
					prebookingOrder.setAvailableQuantity(0);
533
				}
534
				if(prebookingOrder.getAvailableQuantity() == 0) {
535
					prebookingOrder.setCompleteTimestamp(LocalDateTime.now());
536
				}
537
				prebookingOrderRepository.persist(prebookingOrder);
538
 
539
				prebookingOrderItem.setOrderId(orderId);
540
				prebookingOrderItem.setItemId(prebookingOrder.getItemId());
541
				PrebookingListing prebookingListing = itemIdPrebookingListingMap.get(prebookingOrder.getItemId());
542
				prebookingOrderItem.setAdvanceAmount(prebookingListing.getAdvanceAmount());
543
 
544
				prebookingOrderItemRepository.persist(prebookingOrderItem);
23433 ashik.ali 545
 
546
				walletService.addAmountToWallet(fofoId, prebookingOrder.getId(), WalletReferenceType.PREBOOKING_ORDER, "Advance Amount credited for Prebooking Order", prebookingListing.getAdvanceAmount());
23418 ashik.ali 547
			}
548
 
549
		}
550
	}
551
 
552
	private Map<Integer, PrebookingListing> prebookingListingsToItemIdPrebookingListingMap(List<PrebookingListing> prebookingListings){
553
		Map<Integer, PrebookingListing> itemIdPrebookingListingMap = new HashMap<>();
554
		for(PrebookingListing prebookingListing : prebookingListings) {
555
			itemIdPrebookingListingMap.put(prebookingListing.getItemId(), prebookingListing);
556
		}
557
		return itemIdPrebookingListingMap;
558
	}
559
 
560
 
23377 ashik.ali 561
	private Set<String> serialNumberDetailsToSerialNumbers(Set<SerialNumberDetail> serialNumberDetails){
562
		Set<String> serialNumbers = new HashSet<>();
563
		for(SerialNumberDetail serialNumberDetail : serialNumberDetails) {
564
			if(serialNumberDetail.getSerialNumber() != null && !serialNumberDetail.getSerialNumber().isEmpty()) {
565
				serialNumbers.add(serialNumberDetail.getSerialNumber());
566
			}
567
		}
568
		return serialNumbers;
569
	}
570
 
22859 ashik.ali 571
	@Override
572
	public PdfModel getInvoicePdfModel(int fofoId, int orderId) throws ProfitMandiBusinessException {
573
 
574
		FofoOrder fofoOrder = fofoOrderRepository.selectByFofoIdAndOrderId(fofoId, orderId);
575
 
576
		PdfModel pdfModel = new PdfModel();
577
		pdfModel.setAuther("profitmandi");
578
		pdfModel.setTitle("Retailer Invoice");
579
		pdfModel.setInvoiceDate(fofoOrder.getFormattedDate());
580
 
581
		// insurance calculation
22925 ashik.ali 582
		List<InsurancePolicy> insurancePolicies = insurancePolicyRepository.selectByRetailerIdInvoiceNumber(fofoId, fofoOrder.getInvoiceNumber());
22859 ashik.ali 583
		Set<CustomInsurancePolicy> customInsurancePolicies = new HashSet<>();
584
		final float totalInsuranceTaxRate = 18;
585
		for(InsurancePolicy insurancePolicy : insurancePolicies){
586
			float taxableInsurancePrice = insurancePolicy.getSaleAmount() / (1 + totalInsuranceTaxRate / 100);
587
			CustomInsurancePolicy customInsurancePolicy = new CustomInsurancePolicy();
588
			customInsurancePolicy.setDescription("Damage Protection Plan for device IMEI #" + insurancePolicy.getSerialNumber() + "\n Certificate No. " + insurancePolicy.getPolicyNumber());
589
			customInsurancePolicy.setHsnCode("998716");
590
			customInsurancePolicy.setRate(taxableInsurancePrice);
591
			customInsurancePolicy.setIgstRate(18);
592
			customInsurancePolicy.setIgstAmount(taxableInsurancePrice * 18 /100);
22936 amit.gupta 593
			customInsurancePolicy.setCgstRate(9);
22859 ashik.ali 594
			customInsurancePolicy.setCgstAmount(taxableInsurancePrice * 9 /100);
595
			customInsurancePolicy.setSgstRate(9);
596
			customInsurancePolicy.setSgstAmount(taxableInsurancePrice * 9 /100);
597
			customInsurancePolicy.setNetAmount(insurancePolicy.getSaleAmount());
598
			customInsurancePolicies.add(customInsurancePolicy);
599
		}
600
		pdfModel.setInsurancePolicies(customInsurancePolicies);
23001 amit.gupta 601
		List<String> tncs = new ArrayList<>();
602
		tncs.add("I agree that goods received are in good working condition");
603
		tncs.add("Goods once sold cannot be exchanged or taken back");
604
		tncs.add("Warranty for the goods received by me is the responsibility of the manufacturer only.");
605
        if(pdfModel.getInsurancePolicies() != null && pdfModel.getInsurancePolicies().size() > 0) {
23370 ashik.ali 606
        		tncs.add("Damage protection provided is the responisibility of Protection Provider only");
23001 amit.gupta 607
        }
608
		pdfModel.setTncs(tncs);
22859 ashik.ali 609
		Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
610
		CustomCustomer customCustomer = new CustomCustomer();
611
		customCustomer.setFirstName(customer.getFirstName());
612
		customCustomer.setLastName(customer.getLastName());
613
		customCustomer.setEmailId(customer.getEmailId());
614
		customCustomer.setMobileNumber(customer.getMobileNumber());
23370 ashik.ali 615
		customCustomer.setGstNumber(fofoOrder.getCustomerGstNumber());
22859 ashik.ali 616
		CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId()); 
617
		customCustomer.setAddress(this.createCustomAddress(customerAddress));
618
		pdfModel.setCustomer(customCustomer);
619
		pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
620
		pdfModel.setTotalAmount(fofoOrder.getTotalAmount());
621
 
622
		Retailer retailer = retailerRepository.selectById(fofoId);
623
		PrivateDealUser privateDealUser = null;
624
		try{
625
			privateDealUser = privateDealUserRepository.selectById(retailer.getId());
626
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
627
			LOGGER.error("Private Deal User not found : ", profitMandiBusinessException);
628
		}
629
 
630
		User user = userRepository.selectById(userAccountRepository.selectUserIdByRetailerId(retailer.getId()));
631
		CustomRetailer customRetailer = new CustomRetailer();
632
		customRetailer.setBusinessName(retailer.getName());
633
		customRetailer.setMobileNumber(user.getMobileNumber());
22933 ashik.ali 634
		//customRetailer.setTinNumber(retailer.getNumber());
22859 ashik.ali 635
		if(privateDealUser == null){
636
			customRetailer.setGstNumber(null);
637
		}else{
638
			if(null != privateDealUser.getCounterId()){
639
				Counter counter = counterRepository.selectById(privateDealUser.getCounterId());
640
				customRetailer.setGstNumber(counter.getGstin());
641
			}else{
642
				customRetailer.setGstNumber(null);
643
			}
644
		}
645
		Address retailerAddress = addressRepository.selectById(retailerRegisteredAddressRepository.selectAddressIdByRetailerId(retailer.getId()));
646
		customRetailer.setAddress(this.createCustomAddress(retailerAddress));
647
		pdfModel.setRetailer(customRetailer);
22925 ashik.ali 648
		List<FofoOrderItem> fofoOrderItems = this.getByOrderId(fofoOrder.getId());
22859 ashik.ali 649
 
650
		Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();
651
		for(FofoOrderItem fofoOrderItem : fofoOrderItems){
652
			CustomOrderItem customFofoOrderItem = new CustomOrderItem();
653
			float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
654
			float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
655
			float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
656
 
657
			customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));
23377 ashik.ali 658
			customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
659
			Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());
660
			//LOGGER.info("serialNumbers {}", serialNumbers);
661
			//LOGGER.info("serialNumbers is empty {}", serialNumbers.isEmpty());
662
			if(!serialNumbers.isEmpty()) {
663
				customFofoOrderItem.setDescription(customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
664
			}
22859 ashik.ali 665
			customFofoOrderItem.setRate(taxableSellingPrice);
666
			customFofoOrderItem.setDiscount(taxableDiscountPrice);
667
			customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());
668
			customFofoOrderItem.setNetAmount((fofoOrderItem.getSellingPrice()-fofoOrderItem.getDiscount())*fofoOrderItem.getQuantity());
669
			float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
670
			float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
671
			float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
672
			customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
673
			customFofoOrderItem.setIgstAmount(igstAmount);
674
			customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
675
			customFofoOrderItem.setCgstAmount(cgstAmount);
676
			customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
677
			customFofoOrderItem.setSgstAmount(sgstAmount);
678
			customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
679
			customerFofoOrderItems.add(customFofoOrderItem);
680
		}
681
		pdfModel.setOrderItems(customerFofoOrderItems);
682
		return pdfModel;
683
	}
684
 
685
	public String getBillingAddress(CustomerAddress customerAddress) {
686
		StringBuilder address = new StringBuilder();
687
		if ((customerAddress.getLine1() != null) && (!customerAddress.getLine1().isEmpty())) {
688
			address.append(customerAddress.getLine1());
689
			address.append(", ");
690
		}
691
 
692
		if ((customerAddress.getLine2() != null) && (!customerAddress.getLine2().isEmpty())) {
693
			address.append(customerAddress.getLine2());
694
			address.append(", ");
695
		}
696
 
697
		if ((customerAddress.getLandmark() != null) && (!customerAddress.getLandmark().isEmpty())) {
698
			address.append(customerAddress.getLandmark());
699
			address.append(", ");
700
		}
701
 
702
		if ((customerAddress.getCity() != null) && (!customerAddress.getCity().isEmpty())) {
703
			address.append(customerAddress.getCity());
704
			address.append(", ");
705
		}
706
 
707
		if ((customerAddress.getState() != null) && (!customerAddress.getState().isEmpty())) {
708
			address.append(customerAddress.getState());
709
		}
710
 
711
		if ((customerAddress.getPinCode() != null) && (!customerAddress.getPinCode().isEmpty())) {
712
			address.append("- ");
713
			address.append(customerAddress.getPinCode());
714
		}
715
 
716
		return address.toString();
717
	}
718
 
719
	@Override
720
	public List<CartFofo> cartCheckout(String cartJson) throws ProfitMandiBusinessException{
721
		try{
722
			JSONObject cartObject = new JSONObject(cartJson);
723
			Iterator<?> keys = cartObject.keys();
724
 
725
			Set<Integer> itemIds = new HashSet<>();
726
			List<CartFofo> cartItems = new ArrayList<CartFofo>();
727
 
728
			while( keys.hasNext() ) {
729
				String key = (String)keys.next();
730
				if ( cartObject.get(key) instanceof JSONObject ) {
731
					LOGGER.info(cartObject.get(key).toString());
732
				}
733
				CartFofo cf = new CartFofo();
734
				cf.setItemId(cartObject.getJSONObject(key).getInt("itemId"));
735
				cf.setQuantity(cartObject.getJSONObject(key).getInt("quantity"));
736
 
737
				if (cf.getQuantity() <= 0){
738
					continue;
739
				}
740
				cartItems.add(cf);
741
				itemIds.add(cartObject.getJSONObject(key).getInt("itemId"));
742
			}
743
			Map<Integer, Item>  itemMap = new HashMap<Integer, Item>();
744
			if (itemIds.size() > 0){
745
				List<Item> items = itemRepository.selectByIds(itemIds);
746
				for (Item i : items){
747
					itemMap.put(i.getId(), i);
748
				}
749
 
750
			}
751
			for (CartFofo cf : cartItems){
752
				Item i = itemMap.get(cf.getItemId());
753
				if (i == null){
754
					continue;
755
				}
756
				cf.setDisplayName(getValidName(i.getBrand())+" "+getValidName(i.getModelName())+" "+getValidName(i.getModelNumber())+" "+getValidName(i.getColor()).replaceAll("\\s+", " "));
757
				cf.setItemType(i.getType());
758
			}
759
			return cartItems;
760
		}catch (Exception e) {
761
			LOGGER.error("Unable to Prepare cart to place order...", e);
22925 ashik.ali 762
			throw new ProfitMandiBusinessException("cartData", cartJson, "FFORDR_1006");
22859 ashik.ali 763
		}
764
	}
765
 
23202 ashik.ali 766
	@Override
767
	public Map<String, Object> getSaleHistory(int fofoId, SearchType searchType, String searchValue, String startTimeString,
768
			String endTimeString, int offset, int limit) throws ProfitMandiBusinessException {
769
		LocalDateTime startDateTime = StringUtils.toDateTime(startTimeString);
770
		LocalDateTime endDateTime = StringUtils.toDateTime(endTimeString);
771
		long countItems = 0;
772
		List<FofoOrder> fofoOrders = new ArrayList<>();
773
 
774
		if(searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()){
775
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
776
			countItems = fofoOrderRepository.selectCountByCustomerMobileNumber(fofoId, searchValue, startDateTime, endDateTime);
777
		}else if(searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()){
778
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
779
			countItems = fofoOrderRepository.selectCountByCustomerName(fofoId, searchValue, startDateTime, endDateTime);
780
		}else if(searchType == SearchType.IMEI && !searchValue.isEmpty()){
781
			fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
782
			countItems = fofoOrderRepository.selectCountBySerialNumber(fofoId, searchValue, startDateTime, endDateTime);
783
		}else if(searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()){
784
			fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
785
			countItems = fofoOrderRepository.selectCountByItemName(fofoId, searchValue, startDateTime, endDateTime);
786
		}else{
787
			fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDateTime, endDateTime, offset, limit);
23297 ashik.ali 788
			countItems = fofoOrderRepository.selectCountByFofoId(fofoId, startDateTime, endDateTime);
23202 ashik.ali 789
		}
790
		Map<String, Object> map = new HashMap<>();
791
 
792
		map.put("saleHistories", fofoOrders);
793
		map.put("start", offset + 1);
794
		map.put("size", countItems);
795
		map.put("searchType", searchType);
23351 ashik.ali 796
		map.put("searchTypes", SearchType.values());
23202 ashik.ali 797
		map.put(ProfitMandiConstants.START_TIME, startTimeString);
798
		map.put(ProfitMandiConstants.END_TIME, endTimeString);
799
		if (fofoOrders.size() < limit){
800
			map.put("end", offset + fofoOrders.size());
801
		}
802
		else{
803
			map.put("end", offset + limit);
804
		}
805
		return map;
806
	}
807
 
808
	@Override
809
	public Map<String, Object> getSaleHistoryPaginated(int fofoId, SearchType searchType, String searchValue, String startTimeString,
810
			String endTimeString, int offset, int limit) throws ProfitMandiBusinessException {
811
		LocalDateTime startDateTime = StringUtils.toDateTime(startTimeString);
812
		LocalDateTime endDateTime = StringUtils.toDateTime(endTimeString);
813
		List<FofoOrder> fofoOrders = new ArrayList<>();
814
 
815
		if(searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()){
816
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
817
		}else if(searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()){
818
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
819
		}else if(searchType == SearchType.IMEI && !searchValue.isEmpty()){
820
			fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
821
		}else if(searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()){
822
			fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
823
		}else{
824
			fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDateTime, endDateTime, offset, limit);
825
		}
826
		Map<String, Object> map = new HashMap<>();
827
 
828
		map.put("saleHistories", fofoOrders);
829
		return map;
830
	}
831
 
832
	private String getFofoStoreCode(int fofoId) throws ProfitMandiBusinessException{
833
		FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
23370 ashik.ali 834
		return fofoStore.getCode();
23202 ashik.ali 835
	}
836
 
837
 
23191 ashik.ali 838
	private CustomerAddress createCustomerAddress(CustomAddress customAddress, int customerId){
839
		CustomerAddress customerAddress = null;
840
		try{
841
			//CustomAddress customAddress = customCustomer.getAddress();
842
			customerAddress = customerAddressRepository.selectByParams(
843
					customAddress.getName(), customAddress.getLine1(), customAddress.getLine2(),
844
					customAddress.getLandmark(),customAddress.getCity(), customAddress.getPinCode(),
845
					customAddress.getState(), customAddress.getPhoneNumber(), customAddress.getCountry(), customerId);
846
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
847
			LOGGER.warn("Customer address not found : ", profitMandiBusinessException);
848
			customerAddress = new CustomerAddress();
849
			this.setCustomerAddress(customerAddress, customAddress);
850
			customerAddress.setCustomerId(customerId);
851
		}
852
		customerAddressRepository.persist(customerAddress);
853
		return customerAddress;
854
	}
855
 
22859 ashik.ali 856
	private String getValidName(String name){
857
		return name!=null?name:"";
858
	}
859
 
860
	private Set<String> toSerialNumbers(Set<FofoLineItem> fofoLineItems){
23377 ashik.ali 861
		Set<String> serialNumbers = new HashSet<>();
862
		for(FofoLineItem fofoLineItem : fofoLineItems) {
23381 amit.gupta 863
			if(fofoLineItem.getSerialNumber() != null && !fofoLineItem.getSerialNumber().isEmpty()) {
23377 ashik.ali 864
				serialNumbers.add(fofoLineItem.getSerialNumber());
22955 ashik.ali 865
			}
23377 ashik.ali 866
		}
867
		return serialNumbers;
22859 ashik.ali 868
	}
869
 
870
 
871
	private PolicyNumberGenerationSequence createPolicyNumberGenerationSequence(){
872
		PolicyNumberGenerationSequence policyNumberGenerationSequence = null;
873
		try{
874
			policyNumberGenerationSequence = policyNumberGenerationSequenceRepository.select();
875
			policyNumberGenerationSequence.setSequence(policyNumberGenerationSequence.getSequence() + 1);
876
			policyNumberGenerationSequenceRepository.persist(policyNumberGenerationSequence);
877
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
878
			policyNumberGenerationSequence = new PolicyNumberGenerationSequence();
879
			policyNumberGenerationSequence.setSequence(1);
880
			policyNumberGenerationSequenceRepository.persist(policyNumberGenerationSequence);
881
		}
882
		return policyNumberGenerationSequence;
883
	}
884
 
885
	private GadgetCopsInsuranceModel createGadgetCopsInsuranceModel(String brand, String modelName, String serialNumber, LocalDate customerDateOfBirth, Customer customer, CustomerAddress customerAddress, InsurancePolicy insurancePolicy){
886
		GadgetCopsInsuranceModel gadgetCopsInsuranceModel = new GadgetCopsInsuranceModel();
887
		gadgetCopsInsuranceModel.setBrand(brand);
888
		gadgetCopsInsuranceModel.setModelName(modelName);
889
		gadgetCopsInsuranceModel.setSerialNumber(serialNumber);
890
		gadgetCopsInsuranceModel.setCustomerFirstName(customer.getFirstName());
891
		gadgetCopsInsuranceModel.setCustomerLastName(customer.getLastName());
892
		gadgetCopsInsuranceModel.setCustomerDateOfBirth(customerDateOfBirth);
893
		gadgetCopsInsuranceModel.setCustomerMobileNumber(customer.getMobileNumber());
894
		gadgetCopsInsuranceModel.setCustomerEmailId(customer.getEmailId());
895
		gadgetCopsInsuranceModel.setCustomerAddress1(customerAddress.getLine1());
896
		gadgetCopsInsuranceModel.setCustomerAddress2(customerAddress.getLine2());
897
		gadgetCopsInsuranceModel.setCustomerCity(customerAddress.getCity());
898
		gadgetCopsInsuranceModel.setCustomerPinCode(customerAddress.getPinCode());
899
		gadgetCopsInsuranceModel.setCustomerState(customerAddress.getState());
900
		gadgetCopsInsuranceModel.setPrice(insurancePolicy.getSellingPrice());
901
		gadgetCopsInsuranceModel.setInvoiceNumber(insurancePolicy.getInvoiceNumber());
902
		gadgetCopsInsuranceModel.setPolicyNumber(insurancePolicy.getPolicyNumber());
903
		return gadgetCopsInsuranceModel;
904
	}
905
 
23394 amit.gupta 906
	private InsurancePolicy createInsurancePolicy(String invoiceNumber, int retailerId, float purchaseAmount, float saleAmount, float sellingPrice, String serialNumber, String modelName, String brand, int policyNumberGenerationSequence, int insuranceProviderId, Customer customer, LocalDate customerDateOfBirth, CustomerAddress customerAddress){
22859 ashik.ali 907
		InsurancePolicy insurancePolicy = new InsurancePolicy();
23394 amit.gupta 908
		insurancePolicy.setInvoiceNumber(invoiceNumber);
22859 ashik.ali 909
		insurancePolicy.setRetailerId(retailerId);
910
		insurancePolicy.setPurchaseAmount(purchaseAmount);
911
		insurancePolicy.setSaleAmount(saleAmount);
912
		insurancePolicy.setSellingPrice(sellingPrice);
913
		insurancePolicy.setSerialNumber(serialNumber);
914
		insurancePolicy.setModelName(modelName);
915
		insurancePolicy.setBrand(brand);
916
		insurancePolicy.setPolicyNumber(StringUtils.generatePolicyNumber(ProfitMandiConstants.POLICY_NUMBER_PREFIX, policyNumberGenerationSequence));
917
		insurancePolicy.setProviderId(insuranceProviderId);
918
		insurancePolicy.setCustomerFirstName(customer.getFirstName());
919
		insurancePolicy.setCustomerLastName(customer.getLastName());
920
		insurancePolicy.setCustomerMobileNumber(customer.getMobileNumber());
921
		insurancePolicy.setCustomerEmailId(customer.getEmailId());
922
		insurancePolicy.setCustomerDateOfBirth(customerDateOfBirth);
923
		insurancePolicy.setCustomerAddress1(customerAddress.getLine1());
924
		insurancePolicy.setCustomerAddress2(customerAddress.getLine2());
925
		insurancePolicy.setCustomerCity(customerAddress.getCity());
926
		insurancePolicy.setCustomerPinCode(customerAddress.getPinCode());
927
		insurancePolicy.setCustomerState(customerAddress.getState());
928
		return insurancePolicy;
929
	}
930
 
22872 ashik.ali 931
	private void validateInsuranceMargin(Map<String, Float> insuranceSerialNumberItemPrice, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap, Map<Integer, PriceModel> itemIdMopPriceMap, Map<Float, GadgetCopsInsuranceCalc> insurancePricesMap, Map<String, Float> insuranceSerialNumberSaleAmount) throws ProfitMandiBusinessException{
22859 ashik.ali 932
		Map<Float, Float> invalidInsuranceMarginAmount = new HashMap<>();
933
		for(Map.Entry<String, Float> entry : insuranceSerialNumberItemPrice.entrySet()){
22872 ashik.ali 934
			int itemId = this.getItemIdFromSerialNumber(itemIdCustomFofoOrderItemMap, entry.getKey());
22859 ashik.ali 935
			float itemPurchasePrice = itemIdMopPriceMap.get(itemId).getPrice();
936
			float itemSellingPrice = entry.getValue();
937
			float itemMargin = itemSellingPrice - itemPurchasePrice;
938
			float insurancePurchasePrice = insurancePricesMap.get(entry.getValue()).getDealerPrice();
939
			float insuranceSellingPrice = insuranceSerialNumberSaleAmount.get(entry.getKey());
940
			float insuranceMargin = insuranceSellingPrice - insurancePurchasePrice;
941
			if(insuranceMargin < (itemMargin * 30 / 100)){
942
				invalidInsuranceMarginAmount.put(insuranceMargin, (itemMargin * 30 / 100));
943
			}
944
		}
945
		if(!invalidInsuranceMarginAmount.isEmpty()){
946
			LOGGER.error("insurance marging should be greater than equal to item profit margin insuranceMarginItemIdMargin {}", invalidInsuranceMarginAmount);
22925 ashik.ali 947
			throw new ProfitMandiBusinessException("invalidInsuranceMarginAmount", invalidInsuranceMarginAmount, "FFORDR_1007");
22859 ashik.ali 948
		}
949
	}
950
 
951
	private void validateInsuranceAmount(Map<String, Float> insuranceSerialNumberItemPrice, Map<String, Float> insuranceSerialNumberSaleAmount, Map<Float, GadgetCopsInsuranceCalc> insurancePricesMap) throws ProfitMandiBusinessException{
952
		Map<Float, Float> invalidInsurancePurchaseSaleAmount = new HashMap<>();
953
		Map<Float, Float> invalidInsuranceSalePurchaseAmount = new HashMap<>();
954
		for(Map.Entry<String, Float> entry : insuranceSerialNumberItemPrice.entrySet()){
955
			if(insuranceSerialNumberSaleAmount.get(entry.getKey()) < insurancePricesMap.get(entry.getValue()).getDealerPrice()){
956
				invalidInsurancePurchaseSaleAmount.put(insurancePricesMap.get(entry.getValue()).getDealerPrice(), insuranceSerialNumberSaleAmount.get(entry.getKey()));
957
			}
958
 
959
			if(insuranceSerialNumberSaleAmount.get(entry.getKey()) > insurancePricesMap.get(entry.getValue()).getSellingPrice()){
960
				invalidInsuranceSalePurchaseAmount.put(insuranceSerialNumberSaleAmount.get(entry.getKey()), insurancePricesMap.get(entry.getValue()).getDealerPrice());
961
			}
962
		}
963
 
964
		// insurance sale amount can not be lesser than insurance purchase amount
965
		if(!invalidInsurancePurchaseSaleAmount.isEmpty()){
966
			LOGGER.error("Invalid Insurance prices [{}], insurance sale amount can not be lesser than insurance purchase amount", invalidInsurancePurchaseSaleAmount);
22925 ashik.ali 967
			throw new ProfitMandiBusinessException("invalidInsurancePurchaseSaleAmount", invalidInsurancePurchaseSaleAmount, "FFORDR_1008");
22859 ashik.ali 968
		}
969
 
970
		if(!invalidInsuranceSalePurchaseAmount.isEmpty()){
971
			LOGGER.error("Invalid Insurance prices [{}], insurance sale amount can not be greater than than insurance max amount", invalidInsuranceSalePurchaseAmount);
22925 ashik.ali 972
			throw new ProfitMandiBusinessException("invalidInsuranceSalePurchaseAmount", invalidInsuranceSalePurchaseAmount, "FFORDR_1009");
22859 ashik.ali 973
		}
974
	}
975
 
22872 ashik.ali 976
	private void validateMopPrice(Map<Integer, PriceModel> itemIdMopPriceMap, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException{
22859 ashik.ali 977
		Map<Integer, Float> invalidMopItemIdPriceMap = new HashMap<>();
978
		Map<Integer, Float> invalidDiscountAmountMap = new HashMap<>();
979
		//Map<Integer, PriceModel> itemIdMopPriceMap = pricingService.getPurchasePriceMopPriceNotFound(itemIds, fofoId);
980
		for(Map.Entry<Integer, PriceModel> entry : itemIdMopPriceMap.entrySet()){
22872 ashik.ali 981
			CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoLineItemMap.get(entry.getKey());
982
			if(entry.getValue().getPrice() < Float.MAX_VALUE && customFofoOrderItem.getSellingPrice() < entry.getValue().getPrice()){
983
				invalidMopItemIdPriceMap.put(entry.getKey(), customFofoOrderItem.getSellingPrice());
22859 ashik.ali 984
			}
22872 ashik.ali 985
			if(entry.getValue().isMop() && customFofoOrderItem.getDiscountAmount() > entry.getValue().getMaxDiscountAmount()){
986
				invalidDiscountAmountMap.put(entry.getKey(), customFofoOrderItem.getDiscountAmount());
987
			}
22859 ashik.ali 988
		}
989
 
990
		if(!invalidMopItemIdPriceMap.isEmpty()){
991
			LOGGER.error("Invalid itemIds selling prices{} should be greater than mop prices {}", invalidMopItemIdPriceMap, itemIdMopPriceMap);
22925 ashik.ali 992
			throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidMopItemIdPriceMap, "FFORDR_1010");
22859 ashik.ali 993
		}
994
 
995
		if(!invalidMopItemIdPriceMap.isEmpty()){
996
			LOGGER.error("Invalid itemIds discount amounts {} should be less than maxDiscount prices {}", invalidDiscountAmountMap, itemIdMopPriceMap);
22925 ashik.ali 997
			throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidDiscountAmountMap, "FFORDR_1011");
22859 ashik.ali 998
		}
999
	}
1000
 
1001
	private LocalDate validateCustomerDateOfBirth(String customerDateOfBirthString) throws ProfitMandiBusinessException{
1002
		LocalDate customerDateOfBirth = null;
1003
		try{
1004
			customerDateOfBirth = StringUtils.toDate(customerDateOfBirthString);
1005
		}catch(DateTimeException dateTimeException){
1006
			LOGGER.error("Unable to parse dateOfBirth", dateTimeException);
22925 ashik.ali 1007
			throw new ProfitMandiBusinessException("dateOfBirth", customerDateOfBirthString, "FFORDR_1012");
22859 ashik.ali 1008
		}
1009
		return customerDateOfBirth;
1010
	}
1011
 
1012
	private void updateInventoryItemsAndScanRecord(Set<InventoryItem> inventoryItems, int fofoId, Map<Integer, Integer> inventoryItemQuantityUsed){
1013
		for(InventoryItem inventoryItem : inventoryItems){
1014
			inventoryItem.setLastScanType(ScanType.SALE);
1015
			inventoryItemRepository.persist(inventoryItem);
1016
			ScanRecord scanRecord = new ScanRecord();
1017
			scanRecord.setInventoryItemId(inventoryItem.getId());
1018
			scanRecord.setFofoId(fofoId);
1019
			//correct this
1020
			scanRecord.setQuantity(inventoryItemQuantityUsed.get(inventoryItem.getId()));
1021
			scanRecord.setType(ScanType.SALE);
1022
			scanRecordRepository.persist(scanRecord);
1023
		}
1024
	}
1025
 
1026
	private void createFofoLineItem(int fofoOrderItemId, Set<InventoryItem> inventoryItems, Map<Integer, Integer> inventoryItemIdQuantityUsed){
1027
		for(InventoryItem inventoryItem : inventoryItems){
1028
			FofoLineItem fofoLineItem = new FofoLineItem();
1029
			fofoLineItem.setFofoOrderItemId(fofoOrderItemId);
1030
			fofoLineItem.setSerialNumber(inventoryItem.getSerialNumber());
1031
			fofoLineItem.setInventoryItemId(inventoryItem.getId());
1032
			fofoLineItem.setQuantity(inventoryItemIdQuantityUsed.get(inventoryItem.getId()));
1033
			fofoLineItemRepository.persist(fofoLineItem);
1034
		}
1035
	}
1036
 
23393 amit.gupta 1037
	private FofoOrderItem createAndGetFofoOrderItem(CustomFofoOrderItem customFofoOrderItem, int fofoOrderId, Map<Integer, Item> itemMap, Set<InventoryItem> inventoryItems, Integer stateId) throws ProfitMandiBusinessException{
22859 ashik.ali 1038
		FofoOrderItem fofoOrderItem = new FofoOrderItem();
1039
		fofoOrderItem.setItemId(customFofoOrderItem.getItemId());
1040
		fofoOrderItem.setQuantity(customFofoOrderItem.getQuantity());
1041
		fofoOrderItem.setSellingPrice(customFofoOrderItem.getSellingPrice());
1042
		fofoOrderItem.setOrderId(fofoOrderId);
1043
		fofoOrderItem.setDp(customFofoOrderItem.getSellingPrice());
1044
		fofoOrderItem.setDiscount(customFofoOrderItem.getDiscountAmount());
1045
		Item item = itemMap.get(customFofoOrderItem.getItemId());
23172 ashik.ali 1046
		Map<Integer, GstRate> itemIdStateTaxRateMap = null;
1047
		Map<Integer, Float> itemIdIgstTaxRateMap = null;
1048
		if(stateId != null){
1049
			itemIdStateTaxRateMap = Utils.getStateTaxRate(new ArrayList<>(itemMap.keySet()), stateId);
1050
		}else{
1051
			itemIdIgstTaxRateMap = Utils.getIgstTaxRate(new ArrayList<>(itemMap.keySet()));
1052
		}
23393 amit.gupta 1053
		float cost = 0;
22859 ashik.ali 1054
		for(InventoryItem inventoryItem : inventoryItems){
23172 ashik.ali 1055
			if(stateId == null){
1056
				fofoOrderItem.setIgstRate(itemIdIgstTaxRateMap.get(inventoryItem.getItemId()));
1057
			}else{
1058
				fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getCgstRate());
1059
				fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getSgstRate());
1060
			}
23418 ashik.ali 1061
 
22859 ashik.ali 1062
			fofoOrderItem.setHsnCode(inventoryItem.getHsnCode());
1063
			break;
1064
		}
23393 amit.gupta 1065
		for(InventoryItem inventoryItem : inventoryItems){
1066
			if(inventoryItem.getSerialNumber() != null) {
1067
				cost += inventoryItem.getUnitPrice() - inventoryItem.getPriceDropAmount();
1068
			} else {
1069
				cost += inventoryItem.getUnitPrice();
23382 amit.gupta 1070
			}
1071
		}
23393 amit.gupta 1072
		cost = cost/customFofoOrderItem.getQuantity();
23382 amit.gupta 1073
		fofoOrderItem.setCost(cost);
22859 ashik.ali 1074
		fofoOrderItem.setBrand(item.getBrand());
1075
		fofoOrderItem.setModelName(item.getModelName());
1076
		fofoOrderItem.setModelNumber(item.getModelNumber());
1077
		fofoOrderItem.setColor(item.getColor());
1078
		fofoOrderItemRepository.persist(fofoOrderItem);
1079
		return fofoOrderItem;
1080
	}
1081
 
1082
	private void updateCurrentInventorySnapshot(List<CurrentInventorySnapshot> currentInventorySnapshots, int fofoId, int itemId, int quantity) throws ProfitMandiBusinessException{
1083
		for(CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots){
1084
			if(currentInventorySnapshot.getItemId() == itemId && currentInventorySnapshot.getFofoId() == fofoId){
1085
				currentInventorySnapshotRepository.updateAvailabilityByItemIdAndFofoId(itemId, fofoId, currentInventorySnapshot.getAvailability() - quantity);
1086
			}
1087
		}
1088
	}
1089
 
23365 ashik.ali 1090
	private void createPaymentOptions(int fofoOrderId, Set<CustomPaymentOption> customPaymentOptions) throws ProfitMandiBusinessException{
22859 ashik.ali 1091
		for(CustomPaymentOption customPaymentOption : customPaymentOptions){
23371 ashik.ali 1092
			if(customPaymentOption.getAmount() > 0) {
23546 ashik.ali 1093
				PaymentOptionTransaction paymentOptionTransaction = new PaymentOptionTransaction();
1094
				paymentOptionTransaction.setReferenceId(fofoOrderId);
1095
				paymentOptionTransaction.setPaymentOptionId(customPaymentOption.getPaymentOptionId());
1096
				paymentOptionTransaction.setReferenceType(PaymentOptionReferenceType.ORDER);
1097
				paymentOptionTransaction.setAmount(customPaymentOption.getAmount());
1098
				paymentOptionTransactionRepository.persist(paymentOptionTransaction);
23371 ashik.ali 1099
			}
22859 ashik.ali 1100
		}
1101
	}
1102
 
23369 ashik.ali 1103
	private FofoOrder createAndGetFofoOrder(int customerId, String customerGstNumber, int fofoId, InvoiceNumberGenerationSequence invoiceNumberGenerationSequence, float totalAmount, int customerAddressId){
22859 ashik.ali 1104
		FofoOrder fofoOrder = new FofoOrder();
23369 ashik.ali 1105
		fofoOrder.setCustomerGstNumber(customerGstNumber);
22859 ashik.ali 1106
		fofoOrder.setCustomerId(customerId);
1107
		fofoOrder.setFofoId(fofoId);
23370 ashik.ali 1108
		fofoOrder.setInvoiceNumber(invoiceNumberGenerationSequence.getPrefix() + "/" + invoiceNumberGenerationSequence.getSequence());
22859 ashik.ali 1109
		fofoOrder.setTotalAmount(totalAmount);
1110
		fofoOrder.setCustomerAddressId(customerAddressId);
1111
		fofoOrderRepository.persist(fofoOrder);
1112
		return fofoOrder;
1113
	}
1114
 
1115
	private Customer createAndGetCustomer(CustomCustomer customCustomer) throws ProfitMandiBusinessException{
1116
		Customer customer = null;
1117
		try{
1118
			customer = customerRepository.selectByMobileNumber(customCustomer.getMobileNumber());
1119
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
1120
			LOGGER.error("Error : ", profitMandiBusinessException);
1121
			customer = new Customer();
1122
		}
23190 ashik.ali 1123
		customer.setFirstName(customCustomer.getFirstName());
1124
		customer.setLastName(customCustomer.getLastName());
1125
		customer.setEmailId(customCustomer.getEmailId());
1126
		customer.setMobileNumber(customCustomer.getMobileNumber());
1127
		customerRepository.persist(customer);
22859 ashik.ali 1128
		return customer;
1129
	}
1130
 
23202 ashik.ali 1131
	private InvoiceNumberGenerationSequence createAndGetInvoiceNumberGenerationSequence(int fofoId, String fofoStoreCode){
22859 ashik.ali 1132
		InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;
1133
		try{
1134
			invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);
1135
			invoiceNumberGenerationSequence.setSequence(invoiceNumberGenerationSequence.getSequence() + 1);
1136
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
1137
			invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();
1138
			invoiceNumberGenerationSequence.setFofoId(fofoId);
23370 ashik.ali 1139
			invoiceNumberGenerationSequence.setPrefix(fofoStoreCode);
22859 ashik.ali 1140
			invoiceNumberGenerationSequence.setSequence(1);
1141
		}
1142
		invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);
1143
		return invoiceNumberGenerationSequence;
1144
	}
1145
 
22872 ashik.ali 1146
	private void validateItemsSerializedNonSerialized(List<Item> items, Map<Integer, CustomFofoOrderItem> customFofoOrderItemMap) throws ProfitMandiBusinessException{
22859 ashik.ali 1147
 		List<Integer> invalidItemIdSerialNumbers = new ArrayList<Integer>();
1148
		List<Integer> itemIdNonSerializedSerialNumbers = new ArrayList<Integer>();
1149
		for (Item i : items){
22872 ashik.ali 1150
			CustomFofoOrderItem customFofoOrderItem = customFofoOrderItemMap.get(i.getId());
1151
			if (i.getType().equals(ItemType.SERIALIZED)){
1152
				if (customFofoOrderItem == null || customFofoOrderItem.getSerialNumberDetails().isEmpty()){
1153
					invalidItemIdSerialNumbers.add(i.getId());
22859 ashik.ali 1154
				}
23202 ashik.ali 1155
			}else{
23377 ashik.ali 1156
				Set<String> serialNumbers = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());
1157
				if (customFofoOrderItem == null || !serialNumbers.isEmpty()){
22872 ashik.ali 1158
					itemIdNonSerializedSerialNumbers.add(i.getId());
22859 ashik.ali 1159
				}
1160
			}
1161
		}
1162
 
1163
		if(!invalidItemIdSerialNumbers.isEmpty()){
1164
			LOGGER.error("Invalid itemId's serialNumbers for serialized{}", invalidItemIdSerialNumbers);
1165
			// itemId's are serialized you are saying these are not serialized
22925 ashik.ali 1166
			throw new ProfitMandiBusinessException("invalidItemIdSerialNumbers", invalidItemIdSerialNumbers, "FFORDR_1013");
22859 ashik.ali 1167
		}
1168
 
1169
		if(!itemIdNonSerializedSerialNumbers.isEmpty()){
1170
			LOGGER.error("Invalid itemId's serialNumbers for non serialized{}", itemIdNonSerializedSerialNumbers);
1171
			// itemId's are non serialized you are saying these are serialized
22925 ashik.ali 1172
			throw new ProfitMandiBusinessException("itemIdNonSerializedSerialNumbers", itemIdNonSerializedSerialNumbers, "FFORDR_1014");
22859 ashik.ali 1173
		}
1174
	}
1175
 
22872 ashik.ali 1176
	private void validateCurrentInventorySnapshotQuantities(List<CurrentInventorySnapshot> currentInventorySnapshots, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap) throws ProfitMandiBusinessException{
1177
		if(itemIdCustomFofoOrderItemMap.keySet().size() != currentInventorySnapshots.size()){
22859 ashik.ali 1178
			throw new ProfitMandiBusinessException("quantiiesSize", currentInventorySnapshots.size(), "");
1179
		}
1180
		List<ItemIdQuantityAvailability> itemIdQuantityAvailabilities = new ArrayList<>(); //this is for error
1181
		LOGGER.info("currentInventorySnapshots "+currentInventorySnapshots);
22872 ashik.ali 1182
		LOGGER.info("CustomFofoLineItemMap {}", itemIdCustomFofoOrderItemMap);
22859 ashik.ali 1183
		for(CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots){
22872 ashik.ali 1184
			CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoOrderItemMap.get(currentInventorySnapshot.getItemId());
1185
			LOGGER.info("customFofoOrderItem {}", customFofoOrderItem);
1186
			if(customFofoOrderItem.getQuantity() > currentInventorySnapshot.getAvailability()){
22859 ashik.ali 1187
					ItemIdQuantityAvailability itemIdQuantityAvailability = new ItemIdQuantityAvailability();
1188
					itemIdQuantityAvailability.setItemId(customFofoOrderItem.getItemId());
1189
					Quantity quantity = new Quantity();
1190
					quantity.setAvailable(currentInventorySnapshot.getAvailability());
1191
					quantity.setRequested(customFofoOrderItem.getQuantity());
1192
					itemIdQuantityAvailability.setQuantity(quantity);
1193
					itemIdQuantityAvailabilities.add(itemIdQuantityAvailability);
1194
				}
1195
		}
1196
 
1197
		if(!itemIdQuantityAvailabilities.isEmpty()){
1198
			// itemIdQuantity request is not valid
1199
			LOGGER.error("Requested quantities should not be greater than currently available quantities {}", itemIdQuantityAvailabilities);
22925 ashik.ali 1200
			throw new ProfitMandiBusinessException("itemIdQuantityAvailabilities", itemIdQuantityAvailabilities, "FFORDR_1015");
22859 ashik.ali 1201
		}
1202
	}
1203
 
22872 ashik.ali 1204
	private int getItemIdFromSerialNumber(Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap, String serialNumber){
1205
		int itemId = 0;
1206
		for(Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoOrderItemMap.entrySet()){
1207
			Set<SerialNumberDetail> serialNumberDetails = entry.getValue().getSerialNumberDetails();
1208
			for(SerialNumberDetail serialNumberDetail : serialNumberDetails){
1209
				if(serialNumberDetail.getSerialNumber().equals(serialNumber)){
1210
					itemId = entry.getKey();
1211
					break;
1212
				}
22859 ashik.ali 1213
			}
1214
		}
22872 ashik.ali 1215
		return itemId;
22859 ashik.ali 1216
	}
1217
 
1218
	private Map<Integer, Item> toItemMap(List<Item> items){
22955 ashik.ali 1219
		Function<Item, Integer> itemIdFunction = new Function<Item, Integer>() {
1220
			@Override
1221
			public Integer apply(Item item) {
1222
				return item.getId();
1223
			}
1224
		};
1225
		Function<Item, Item> itemFunction = new Function<Item, Item>() {
1226
			@Override
1227
			public Item apply(Item item) {
1228
				return item;
1229
			}
1230
		};
1231
		return items.stream().collect(Collectors.toMap(itemIdFunction, itemFunction));
22859 ashik.ali 1232
	}
1233
 
23190 ashik.ali 1234
	private void setCustomerAddress(CustomerAddress customerAddress, CustomAddress customAddress){
22859 ashik.ali 1235
		customerAddress.setName(customAddress.getName());
1236
		customerAddress.setLine1(customAddress.getLine1());
1237
		customerAddress.setLine2(customAddress.getLine2());
1238
		customerAddress.setLandmark(customAddress.getLandmark());
1239
		customerAddress.setCity(customAddress.getCity());
1240
		customerAddress.setPinCode(customAddress.getPinCode());
1241
		customerAddress.setState(customAddress.getState());
1242
		customerAddress.setCountry(customAddress.getCountry());
1243
		customerAddress.setPhoneNumber(customAddress.getPhoneNumber());
1244
	}
1245
 
1246
	private CustomAddress createCustomAddress(Address address){
1247
		CustomAddress customAddress = new CustomAddress();
1248
		customAddress.setName(address.getName());
1249
		customAddress.setLine1(address.getLine1());
1250
		customAddress.setLine2(address.getLine2());
1251
		customAddress.setLandmark(address.getLandmark());
1252
		customAddress.setCity(address.getCity());
1253
		customAddress.setPinCode(address.getPinCode());
1254
		customAddress.setState(address.getState());
1255
		customAddress.setCountry(address.getCountry());
1256
		customAddress.setPhoneNumber(address.getPhoneNumber());
1257
		return customAddress;
1258
	}
1259
 
1260
	private CustomAddress createCustomAddress(CustomerAddress customerAddress){
1261
		CustomAddress customAddress = new CustomAddress();
1262
		customAddress.setName(customerAddress.getName());
1263
		customAddress.setLine1(customerAddress.getLine1());
1264
		customAddress.setLine2(customerAddress.getLine2());
1265
		customAddress.setLandmark(customerAddress.getLandmark());
1266
		customAddress.setCity(customerAddress.getCity());
1267
		customAddress.setPinCode(customerAddress.getPinCode());
1268
		customAddress.setState(customerAddress.getState());
1269
		customAddress.setCountry(customerAddress.getCountry());
1270
		customAddress.setPhoneNumber(customerAddress.getPhoneNumber());
1271
		return customAddress;
1272
	}
1273
 
1274
	private void validatePaymentOptionsAndTotalAmount(Set<CustomPaymentOption> customPaymentOptions, float totalAmount) throws ProfitMandiBusinessException
1275
	{
23365 ashik.ali 1276
		Set<Integer> paymentOptionIds = new HashSet<>();
1277
 
22859 ashik.ali 1278
		float calculatedAmount = 0;
1279
		for(CustomPaymentOption customPaymentOption : customPaymentOptions){
23365 ashik.ali 1280
			paymentOptionIds.add(customPaymentOption.getPaymentOptionId());
1281
			calculatedAmount = calculatedAmount + customPaymentOption.getAmount();
22859 ashik.ali 1282
		}
1283
		if(calculatedAmount != totalAmount){
22863 ashik.ali 1284
			LOGGER.warn("Error occured while validating payment options amount[{}] != TotalAmount [{}]", calculatedAmount, totalAmount);
22925 ashik.ali 1285
			throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_CALCULATED_AMOUNT, calculatedAmount, "FFORDR_1016");
22859 ashik.ali 1286
		}
23365 ashik.ali 1287
 
1288
		List<Integer> foundPaymentOptionIds = paymentOptionRepository.selectIdsByIds(paymentOptionIds);
1289
		if(foundPaymentOptionIds.size() != paymentOptionIds.size()) {
1290
			paymentOptionIds.removeAll(foundPaymentOptionIds);
1291
			throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_ID, paymentOptionIds, "FFORDR_1017");
1292
		}
22859 ashik.ali 1293
	}
22925 ashik.ali 1294
 
1295
	@Override
1296
	public List<FofoOrderItem> getByOrderId(int orderId) throws ProfitMandiBusinessException {
1297
		List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(orderId);
1298
		if(!fofoOrderItems.isEmpty()){
1299
			List<FofoOrderItem> newFofoOrderItems = new ArrayList<>();
1300
			Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = this.toFofoOrderItemIdFofoLineItems(fofoOrderItems);
1301
			Iterator<FofoOrderItem> fofoOrderItemsIterator = fofoOrderItems.iterator();
1302
			while(fofoOrderItemsIterator.hasNext()){
1303
				FofoOrderItem fofoOrderItem = fofoOrderItemsIterator.next();
1304
				fofoOrderItem.setFofoLineItems(fofoOrderItemIdFofoLineItemsMap.get(fofoOrderItem.getId()));
1305
				newFofoOrderItems.add(fofoOrderItem);
1306
				fofoOrderItemsIterator.remove();
1307
			}
1308
			fofoOrderItems = newFofoOrderItems;
1309
		}
1310
		return fofoOrderItems;
1311
	}
1312
 
1313
	private Set<Integer> toFofoOrderItemIds(List<FofoOrderItem> fofoOrderItems){
22955 ashik.ali 1314
		Function<FofoOrderItem, Integer> fofoOrderItemToFofoOrderItemIdFunction = new Function<FofoOrderItem, Integer>() {
1315
			@Override
1316
			public Integer apply(FofoOrderItem fofoOrderItem) {
1317
				return fofoOrderItem.getId();
1318
			}
1319
		};
1320
		return fofoOrderItems.stream().map(fofoOrderItemToFofoOrderItemIdFunction).collect(Collectors.toSet());
22925 ashik.ali 1321
	}
1322
 
1323
	private Map<Integer, Set<FofoLineItem>> toFofoOrderItemIdFofoLineItems(List<FofoOrderItem> fofoOrderItems){
1324
		Set<Integer> fofoOrderItemIds = this.toFofoOrderItemIds(fofoOrderItems);
1325
		List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIds);
1326
		Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = new HashMap<>();
1327
		for(FofoLineItem fofoLineItem : fofoLineItems){
1328
			if(!fofoOrderItemIdFofoLineItemsMap.containsKey(fofoLineItem.getFofoOrderItemId())){
1329
				Set<FofoLineItem> fofoLineItems2 = new HashSet<>();
1330
				fofoLineItems2.add(fofoLineItem);
1331
				fofoOrderItemIdFofoLineItemsMap.put(fofoLineItem.getFofoOrderItemId(), fofoLineItems2);
1332
			}else{
1333
				fofoOrderItemIdFofoLineItemsMap.get(fofoLineItem.getFofoOrderItemId()).add(fofoLineItem);
1334
			}
1335
		}
1336
		return fofoOrderItemIdFofoLineItemsMap;
1337
	}
23418 ashik.ali 1338
 
1339
	private String getOtpString(){
1340
		Random rndm_method = new Random();
1341
		String numbers ="0123456789";
1342
		char[] otp = new char[5];
22859 ashik.ali 1343
 
23418 ashik.ali 1344
		for (int i = 0; i < 5; i++){
1345
			otp[i] = numbers.charAt(rndm_method.nextInt(numbers.length()));
1346
		}
1347
		return String.valueOf(otp);
1348
	}
1349
 
1350
	private void sendOtp(String otp_text, String phone, Map<Integer, Float> itemIdAdvanceAmount){
1351
		Map<Integer, String> itemIdDescriptionMap = inventoryService.getItemIdDescriptionMap(itemIdAdvanceAmount.keySet());
1352
		StringBuilder itemIdAdvanceAmountString = new StringBuilder();
1353
		int index = 0;
1354
		for(Map.Entry<Integer, Float> itemIdAdvanceAmountEntry : itemIdAdvanceAmount.entrySet()) {
1355
			itemIdAdvanceAmountString.append(itemIdDescriptionMap.get(itemIdAdvanceAmountEntry.getKey()));
1356
			itemIdAdvanceAmountString.append("'s Advance amount [");
1357
			itemIdAdvanceAmountString.append(itemIdAdvanceAmountEntry.getValue());
1358
			itemIdAdvanceAmountString.append("]");
1359
			if(index + 1 < itemIdAdvanceAmount.size()) {
1360
				itemIdAdvanceAmountString.append(", ");
1361
			}
1362
			index++;
1363
		}
1364
		String text = "Dear Customer, {0} is the OTP that you have requested for prebooking orders for items {1} Don't share your OTP with anyone.";
1365
		String msg = java.text.MessageFormat.format(text, otp_text, itemIdAdvanceAmountString);
1366
		try {
1367
			Utils.sendSms(msg, phone);
1368
		} catch (URISyntaxException e) {
1369
			// TODO Auto-generated catch block
1370
			e.printStackTrace();
1371
		} catch (IOException e) {
1372
			// TODO Auto-generated catch block
1373
			e.printStackTrace();
1374
		}
1375
 
1376
	}
1377
 
1378
	@Override
1379
	public int generatePrebookingOrdersOtp(String customerEmailId, String customerMobileNumber, Map<Integer, Float> itemIdAdvanceAmount) throws ProfitMandiBusinessException {
1380
		if(!StringUtils.isValidEmailAddress(customerEmailId)){
1381
			LOGGER.error("invalid customer emailId {} ", customerEmailId);
1382
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EMAIL_ID, customerEmailId, "VE_1016");
1383
		}
1384
 
1385
		if(!StringUtils.isValidMobile(customerMobileNumber)){
1386
			LOGGER.error("invalid customer mobileNumber {} ", customerMobileNumber);
1387
			throw new ProfitMandiBusinessException(ProfitMandiConstants.MOBILE_NUMBER, customerMobileNumber, "VE_1071");
1388
		}
1389
 
1390
		List<Otp> otps = otpRepository.selectAllByEmailWithTime(customerEmailId);
1391
		String otp = null;
1392
		if (otps.size() >= 5){
1393
			throw new ProfitMandiBusinessException(ProfitMandiConstants.CUSTOMER_EMAIL_ID, customerEmailId, "FFORDR_1019");
1394
		}
1395
		if (!otps.isEmpty()){
1396
			if (otps.get(0).getCreatedOn().isAfter(LocalDateTime.now().minusMinutes(2))){
1397
				return otps.get(0).getId();
1398
			}else if(otps.get(0).getCreatedOn().isAfter(LocalDateTime.now().minusMinutes(10))){
1399
				otp = otps.get(0).getOtp();
1400
			}
1401
		}
1402
		if (otp == null || otp.isEmpty()){
1403
			otp = getOtpString();
1404
		}
1405
 
1406
		this.sendOtp(otp, customerMobileNumber, itemIdAdvanceAmount);
1407
 
1408
		Otp otp_bean = new Otp();
1409
		otp_bean.setEmail(customerEmailId);
1410
		otp_bean.setMobile(customerMobileNumber);
1411
		otp_bean.setOtp(otp);
1412
		otp_bean.setOtpType(OtpType.PREBOOKING_ORDER);
1413
		otp_bean.setCreatedOn(LocalDateTime.now());
1414
		otp_bean.setExpiryTimestamp(LocalDateTime.now().plusMinutes(10));
1415
		otpRepository.persist(otp_bean);
1416
 
1417
		return otp_bean.getId();
1418
	}
1419
 
1420
	@Override
1421
	public String validateOtp(String customerEmailId, String customerMobileNumber, int otpId, String otpValue)
1422
			throws ProfitMandiBusinessException {
1423
		Otp otp = otpRepository.selectByIdEmailIdMobileNumber(otpId, customerEmailId, customerMobileNumber);
1424
		otp.setTryCount(otp.getTryCount() + 1);
1425
		if (!otp.getOtp().equalsIgnoreCase(otpValue)){
1426
			throw new ProfitMandiBusinessException("otpValue", otpValue, "FFORDR_1020");
1427
		}
1428
		if (otp.isExpired() || otp.isVerified() || otp.getExpiryTimestamp().isBefore(LocalDateTime.now())){
1429
			throw new ProfitMandiBusinessException("otpValue", otpValue, "FFORDR_1021");
1430
		}
1431
		if (otp.getTryCount() >5){
1432
			throw new ProfitMandiBusinessException("otpValue", otpValue, "FFORDR_1022");
1433
		}
1434
		otp.setExpired(true);
1435
		otp.setVerified(true);
1436
		otpRepository.persist(otp);
1437
 
1438
		return ResponseCodeHolder.getMessage("FFORDR_OK_1002");
1439
	}
1440
 
22859 ashik.ali 1441
}