Subversion Repositories SmartDukaan

Rev

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