Subversion Repositories SmartDukaan

Rev

Rev 23418 | Rev 23433 | 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
 
23418 ashik.ali 426
		FofoOrder fofoOrder = this.createAndGetFofoOrder(customer.getId(), customCustomer.getGstNumber(), fofoId, invoiceNumberGenerationSequence, totalAmount - prebookingOrdersTotalAmount, customerAddress.getId());
22859 ashik.ali 427
 
428
		this.createPaymentOptions(fofoOrder.getId(), createOrderRequest.getPaymentOptions());
429
 
23418 ashik.ali 430
		this.processPrebookingOrders(fofoOrder.getId(), prebookingOrders, prebookingOrderItemIdQuantityMap, itemIdPrebookingListingMap);
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
 
517
	private void processPrebookingOrders(int orderId, List<PrebookingOrder> prebookingOrders, Map<Integer, Integer> prebookingOrderItemIdQuantityMap, Map<Integer, PrebookingListing> itemIdPrebookingListingMap) {
518
		//Map<Integer, PrebookingOrder> prebookingOrderIdPrebookingOrderMap = this.prebookingOrdersToPrebookingOrderIdPrebookingOrderMap(prebookingOrders);
519
 
520
		for(PrebookingOrder prebookingOrder : prebookingOrders) {
521
			if(prebookingOrder.getCompleteTimestamp() == null) {
522
				int requestedQuantity = prebookingOrderItemIdQuantityMap.get(prebookingOrder.getItemId());
523
 
524
				PrebookingOrderItem prebookingOrderItem = new PrebookingOrderItem();
525
				if(requestedQuantity < prebookingOrder.getAvailableQuantity()) {
526
					prebookingOrder.setAvailableQuantity(prebookingOrder.getAvailableQuantity() - requestedQuantity);
527
					prebookingOrderItem.setQuantity(requestedQuantity);
528
				}else if(requestedQuantity >= prebookingOrder.getAvailableQuantity()) {
529
					prebookingOrderItem.setQuantity(prebookingOrder.getAvailableQuantity());
530
					prebookingOrder.setAvailableQuantity(0);
531
				}
532
				if(prebookingOrder.getAvailableQuantity() == 0) {
533
					prebookingOrder.setCompleteTimestamp(LocalDateTime.now());
534
				}
535
				prebookingOrderRepository.persist(prebookingOrder);
536
 
537
				prebookingOrderItem.setOrderId(orderId);
538
				prebookingOrderItem.setItemId(prebookingOrder.getItemId());
539
				PrebookingListing prebookingListing = itemIdPrebookingListingMap.get(prebookingOrder.getItemId());
540
				prebookingOrderItem.setAdvanceAmount(prebookingListing.getAdvanceAmount());
541
 
542
				prebookingOrderItemRepository.persist(prebookingOrderItem);
543
			}
544
 
545
		}
546
	}
547
 
548
	private Map<Integer, PrebookingListing> prebookingListingsToItemIdPrebookingListingMap(List<PrebookingListing> prebookingListings){
549
		Map<Integer, PrebookingListing> itemIdPrebookingListingMap = new HashMap<>();
550
		for(PrebookingListing prebookingListing : prebookingListings) {
551
			itemIdPrebookingListingMap.put(prebookingListing.getItemId(), prebookingListing);
552
		}
553
		return itemIdPrebookingListingMap;
554
	}
555
 
556
 
23377 ashik.ali 557
	private Set<String> serialNumberDetailsToSerialNumbers(Set<SerialNumberDetail> serialNumberDetails){
558
		Set<String> serialNumbers = new HashSet<>();
559
		for(SerialNumberDetail serialNumberDetail : serialNumberDetails) {
560
			if(serialNumberDetail.getSerialNumber() != null && !serialNumberDetail.getSerialNumber().isEmpty()) {
561
				serialNumbers.add(serialNumberDetail.getSerialNumber());
562
			}
563
		}
564
		return serialNumbers;
565
	}
566
 
22859 ashik.ali 567
	@Override
568
	public PdfModel getInvoicePdfModel(int fofoId, int orderId) throws ProfitMandiBusinessException {
569
 
570
		FofoOrder fofoOrder = fofoOrderRepository.selectByFofoIdAndOrderId(fofoId, orderId);
571
 
572
		PdfModel pdfModel = new PdfModel();
573
		pdfModel.setAuther("profitmandi");
574
		pdfModel.setTitle("Retailer Invoice");
575
		pdfModel.setInvoiceDate(fofoOrder.getFormattedDate());
576
 
577
		// insurance calculation
22925 ashik.ali 578
		List<InsurancePolicy> insurancePolicies = insurancePolicyRepository.selectByRetailerIdInvoiceNumber(fofoId, fofoOrder.getInvoiceNumber());
22859 ashik.ali 579
		Set<CustomInsurancePolicy> customInsurancePolicies = new HashSet<>();
580
		final float totalInsuranceTaxRate = 18;
581
		for(InsurancePolicy insurancePolicy : insurancePolicies){
582
			float taxableInsurancePrice = insurancePolicy.getSaleAmount() / (1 + totalInsuranceTaxRate / 100);
583
			CustomInsurancePolicy customInsurancePolicy = new CustomInsurancePolicy();
584
			customInsurancePolicy.setDescription("Damage Protection Plan for device IMEI #" + insurancePolicy.getSerialNumber() + "\n Certificate No. " + insurancePolicy.getPolicyNumber());
585
			customInsurancePolicy.setHsnCode("998716");
586
			customInsurancePolicy.setRate(taxableInsurancePrice);
587
			customInsurancePolicy.setIgstRate(18);
588
			customInsurancePolicy.setIgstAmount(taxableInsurancePrice * 18 /100);
22936 amit.gupta 589
			customInsurancePolicy.setCgstRate(9);
22859 ashik.ali 590
			customInsurancePolicy.setCgstAmount(taxableInsurancePrice * 9 /100);
591
			customInsurancePolicy.setSgstRate(9);
592
			customInsurancePolicy.setSgstAmount(taxableInsurancePrice * 9 /100);
593
			customInsurancePolicy.setNetAmount(insurancePolicy.getSaleAmount());
594
			customInsurancePolicies.add(customInsurancePolicy);
595
		}
596
		pdfModel.setInsurancePolicies(customInsurancePolicies);
23001 amit.gupta 597
		List<String> tncs = new ArrayList<>();
598
		tncs.add("I agree that goods received are in good working condition");
599
		tncs.add("Goods once sold cannot be exchanged or taken back");
600
		tncs.add("Warranty for the goods received by me is the responsibility of the manufacturer only.");
601
        if(pdfModel.getInsurancePolicies() != null && pdfModel.getInsurancePolicies().size() > 0) {
23370 ashik.ali 602
        		tncs.add("Damage protection provided is the responisibility of Protection Provider only");
23001 amit.gupta 603
        }
604
		pdfModel.setTncs(tncs);
22859 ashik.ali 605
		Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
606
		CustomCustomer customCustomer = new CustomCustomer();
607
		customCustomer.setFirstName(customer.getFirstName());
608
		customCustomer.setLastName(customer.getLastName());
609
		customCustomer.setEmailId(customer.getEmailId());
610
		customCustomer.setMobileNumber(customer.getMobileNumber());
23370 ashik.ali 611
		customCustomer.setGstNumber(fofoOrder.getCustomerGstNumber());
22859 ashik.ali 612
		CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId()); 
613
		customCustomer.setAddress(this.createCustomAddress(customerAddress));
614
		pdfModel.setCustomer(customCustomer);
615
		pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
616
		pdfModel.setTotalAmount(fofoOrder.getTotalAmount());
617
 
618
		Retailer retailer = retailerRepository.selectById(fofoId);
619
		PrivateDealUser privateDealUser = null;
620
		try{
621
			privateDealUser = privateDealUserRepository.selectById(retailer.getId());
622
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
623
			LOGGER.error("Private Deal User not found : ", profitMandiBusinessException);
624
		}
625
 
626
		User user = userRepository.selectById(userAccountRepository.selectUserIdByRetailerId(retailer.getId()));
627
		CustomRetailer customRetailer = new CustomRetailer();
628
		customRetailer.setBusinessName(retailer.getName());
629
		customRetailer.setMobileNumber(user.getMobileNumber());
22933 ashik.ali 630
		//customRetailer.setTinNumber(retailer.getNumber());
22859 ashik.ali 631
		if(privateDealUser == null){
632
			customRetailer.setGstNumber(null);
633
		}else{
634
			if(null != privateDealUser.getCounterId()){
635
				Counter counter = counterRepository.selectById(privateDealUser.getCounterId());
636
				customRetailer.setGstNumber(counter.getGstin());
637
			}else{
638
				customRetailer.setGstNumber(null);
639
			}
640
		}
641
		Address retailerAddress = addressRepository.selectById(retailerRegisteredAddressRepository.selectAddressIdByRetailerId(retailer.getId()));
642
		customRetailer.setAddress(this.createCustomAddress(retailerAddress));
643
		pdfModel.setRetailer(customRetailer);
22925 ashik.ali 644
		List<FofoOrderItem> fofoOrderItems = this.getByOrderId(fofoOrder.getId());
22859 ashik.ali 645
 
646
		Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();
647
		for(FofoOrderItem fofoOrderItem : fofoOrderItems){
648
			CustomOrderItem customFofoOrderItem = new CustomOrderItem();
649
			float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
650
			float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
651
			float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
652
 
653
			customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));
23377 ashik.ali 654
			customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
655
			Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());
656
			//LOGGER.info("serialNumbers {}", serialNumbers);
657
			//LOGGER.info("serialNumbers is empty {}", serialNumbers.isEmpty());
658
			if(!serialNumbers.isEmpty()) {
659
				customFofoOrderItem.setDescription(customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
660
			}
22859 ashik.ali 661
			customFofoOrderItem.setRate(taxableSellingPrice);
662
			customFofoOrderItem.setDiscount(taxableDiscountPrice);
663
			customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());
664
			customFofoOrderItem.setNetAmount((fofoOrderItem.getSellingPrice()-fofoOrderItem.getDiscount())*fofoOrderItem.getQuantity());
665
			float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
666
			float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
667
			float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
668
			customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
669
			customFofoOrderItem.setIgstAmount(igstAmount);
670
			customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
671
			customFofoOrderItem.setCgstAmount(cgstAmount);
672
			customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
673
			customFofoOrderItem.setSgstAmount(sgstAmount);
674
			customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
675
			customerFofoOrderItems.add(customFofoOrderItem);
676
		}
677
		pdfModel.setOrderItems(customerFofoOrderItems);
678
		return pdfModel;
679
	}
680
 
681
	public String getBillingAddress(CustomerAddress customerAddress) {
682
		StringBuilder address = new StringBuilder();
683
		if ((customerAddress.getLine1() != null) && (!customerAddress.getLine1().isEmpty())) {
684
			address.append(customerAddress.getLine1());
685
			address.append(", ");
686
		}
687
 
688
		if ((customerAddress.getLine2() != null) && (!customerAddress.getLine2().isEmpty())) {
689
			address.append(customerAddress.getLine2());
690
			address.append(", ");
691
		}
692
 
693
		if ((customerAddress.getLandmark() != null) && (!customerAddress.getLandmark().isEmpty())) {
694
			address.append(customerAddress.getLandmark());
695
			address.append(", ");
696
		}
697
 
698
		if ((customerAddress.getCity() != null) && (!customerAddress.getCity().isEmpty())) {
699
			address.append(customerAddress.getCity());
700
			address.append(", ");
701
		}
702
 
703
		if ((customerAddress.getState() != null) && (!customerAddress.getState().isEmpty())) {
704
			address.append(customerAddress.getState());
705
		}
706
 
707
		if ((customerAddress.getPinCode() != null) && (!customerAddress.getPinCode().isEmpty())) {
708
			address.append("- ");
709
			address.append(customerAddress.getPinCode());
710
		}
711
 
712
		return address.toString();
713
	}
714
 
715
	@Override
716
	public List<CartFofo> cartCheckout(String cartJson) throws ProfitMandiBusinessException{
717
		try{
718
			JSONObject cartObject = new JSONObject(cartJson);
719
			Iterator<?> keys = cartObject.keys();
720
 
721
			Set<Integer> itemIds = new HashSet<>();
722
			List<CartFofo> cartItems = new ArrayList<CartFofo>();
723
 
724
			while( keys.hasNext() ) {
725
				String key = (String)keys.next();
726
				if ( cartObject.get(key) instanceof JSONObject ) {
727
					LOGGER.info(cartObject.get(key).toString());
728
				}
729
				CartFofo cf = new CartFofo();
730
				cf.setItemId(cartObject.getJSONObject(key).getInt("itemId"));
731
				cf.setQuantity(cartObject.getJSONObject(key).getInt("quantity"));
732
 
733
				if (cf.getQuantity() <= 0){
734
					continue;
735
				}
736
				cartItems.add(cf);
737
				itemIds.add(cartObject.getJSONObject(key).getInt("itemId"));
738
			}
739
			Map<Integer, Item>  itemMap = new HashMap<Integer, Item>();
740
			if (itemIds.size() > 0){
741
				List<Item> items = itemRepository.selectByIds(itemIds);
742
				for (Item i : items){
743
					itemMap.put(i.getId(), i);
744
				}
745
 
746
			}
747
			for (CartFofo cf : cartItems){
748
				Item i = itemMap.get(cf.getItemId());
749
				if (i == null){
750
					continue;
751
				}
752
				cf.setDisplayName(getValidName(i.getBrand())+" "+getValidName(i.getModelName())+" "+getValidName(i.getModelNumber())+" "+getValidName(i.getColor()).replaceAll("\\s+", " "));
753
				cf.setItemType(i.getType());
754
			}
755
			return cartItems;
756
		}catch (Exception e) {
757
			LOGGER.error("Unable to Prepare cart to place order...", e);
22925 ashik.ali 758
			throw new ProfitMandiBusinessException("cartData", cartJson, "FFORDR_1006");
22859 ashik.ali 759
		}
760
	}
761
 
23202 ashik.ali 762
	@Override
763
	public Map<String, Object> getSaleHistory(int fofoId, SearchType searchType, String searchValue, String startTimeString,
764
			String endTimeString, int offset, int limit) throws ProfitMandiBusinessException {
765
		LocalDateTime startDateTime = StringUtils.toDateTime(startTimeString);
766
		LocalDateTime endDateTime = StringUtils.toDateTime(endTimeString);
767
		long countItems = 0;
768
		List<FofoOrder> fofoOrders = new ArrayList<>();
769
 
770
		if(searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()){
771
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
772
			countItems = fofoOrderRepository.selectCountByCustomerMobileNumber(fofoId, searchValue, startDateTime, endDateTime);
773
		}else if(searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()){
774
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
775
			countItems = fofoOrderRepository.selectCountByCustomerName(fofoId, searchValue, startDateTime, endDateTime);
776
		}else if(searchType == SearchType.IMEI && !searchValue.isEmpty()){
777
			fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
778
			countItems = fofoOrderRepository.selectCountBySerialNumber(fofoId, searchValue, startDateTime, endDateTime);
779
		}else if(searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()){
780
			fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
781
			countItems = fofoOrderRepository.selectCountByItemName(fofoId, searchValue, startDateTime, endDateTime);
782
		}else{
783
			fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDateTime, endDateTime, offset, limit);
23297 ashik.ali 784
			countItems = fofoOrderRepository.selectCountByFofoId(fofoId, startDateTime, endDateTime);
23202 ashik.ali 785
		}
786
		Map<String, Object> map = new HashMap<>();
787
 
788
		map.put("saleHistories", fofoOrders);
789
		map.put("start", offset + 1);
790
		map.put("size", countItems);
791
		map.put("searchType", searchType);
23351 ashik.ali 792
		map.put("searchTypes", SearchType.values());
23202 ashik.ali 793
		map.put(ProfitMandiConstants.START_TIME, startTimeString);
794
		map.put(ProfitMandiConstants.END_TIME, endTimeString);
795
		if (fofoOrders.size() < limit){
796
			map.put("end", offset + fofoOrders.size());
797
		}
798
		else{
799
			map.put("end", offset + limit);
800
		}
801
		return map;
802
	}
803
 
804
	@Override
805
	public Map<String, Object> getSaleHistoryPaginated(int fofoId, SearchType searchType, String searchValue, String startTimeString,
806
			String endTimeString, int offset, int limit) throws ProfitMandiBusinessException {
807
		LocalDateTime startDateTime = StringUtils.toDateTime(startTimeString);
808
		LocalDateTime endDateTime = StringUtils.toDateTime(endTimeString);
809
		List<FofoOrder> fofoOrders = new ArrayList<>();
810
 
811
		if(searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()){
812
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
813
		}else if(searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()){
814
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
815
		}else if(searchType == SearchType.IMEI && !searchValue.isEmpty()){
816
			fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
817
		}else if(searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()){
818
			fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, startDateTime, endDateTime, offset, limit);
819
		}else{
820
			fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDateTime, endDateTime, offset, limit);
821
		}
822
		Map<String, Object> map = new HashMap<>();
823
 
824
		map.put("saleHistories", fofoOrders);
825
		return map;
826
	}
827
 
828
	private String getFofoStoreCode(int fofoId) throws ProfitMandiBusinessException{
829
		FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
23370 ashik.ali 830
		return fofoStore.getCode();
23202 ashik.ali 831
	}
832
 
833
 
23191 ashik.ali 834
	private CustomerAddress createCustomerAddress(CustomAddress customAddress, int customerId){
835
		CustomerAddress customerAddress = null;
836
		try{
837
			//CustomAddress customAddress = customCustomer.getAddress();
838
			customerAddress = customerAddressRepository.selectByParams(
839
					customAddress.getName(), customAddress.getLine1(), customAddress.getLine2(),
840
					customAddress.getLandmark(),customAddress.getCity(), customAddress.getPinCode(),
841
					customAddress.getState(), customAddress.getPhoneNumber(), customAddress.getCountry(), customerId);
842
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
843
			LOGGER.warn("Customer address not found : ", profitMandiBusinessException);
844
			customerAddress = new CustomerAddress();
845
			this.setCustomerAddress(customerAddress, customAddress);
846
			customerAddress.setCustomerId(customerId);
847
		}
848
		customerAddressRepository.persist(customerAddress);
849
		return customerAddress;
850
	}
851
 
22859 ashik.ali 852
	private String getValidName(String name){
853
		return name!=null?name:"";
854
	}
855
 
856
	private Set<String> toSerialNumbers(Set<FofoLineItem> fofoLineItems){
23377 ashik.ali 857
		Set<String> serialNumbers = new HashSet<>();
858
		for(FofoLineItem fofoLineItem : fofoLineItems) {
23381 amit.gupta 859
			if(fofoLineItem.getSerialNumber() != null && !fofoLineItem.getSerialNumber().isEmpty()) {
23377 ashik.ali 860
				serialNumbers.add(fofoLineItem.getSerialNumber());
22955 ashik.ali 861
			}
23377 ashik.ali 862
		}
863
		return serialNumbers;
22859 ashik.ali 864
	}
865
 
866
 
867
	private PolicyNumberGenerationSequence createPolicyNumberGenerationSequence(){
868
		PolicyNumberGenerationSequence policyNumberGenerationSequence = null;
869
		try{
870
			policyNumberGenerationSequence = policyNumberGenerationSequenceRepository.select();
871
			policyNumberGenerationSequence.setSequence(policyNumberGenerationSequence.getSequence() + 1);
872
			policyNumberGenerationSequenceRepository.persist(policyNumberGenerationSequence);
873
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
874
			policyNumberGenerationSequence = new PolicyNumberGenerationSequence();
875
			policyNumberGenerationSequence.setSequence(1);
876
			policyNumberGenerationSequenceRepository.persist(policyNumberGenerationSequence);
877
		}
878
		return policyNumberGenerationSequence;
879
	}
880
 
881
	private GadgetCopsInsuranceModel createGadgetCopsInsuranceModel(String brand, String modelName, String serialNumber, LocalDate customerDateOfBirth, Customer customer, CustomerAddress customerAddress, InsurancePolicy insurancePolicy){
882
		GadgetCopsInsuranceModel gadgetCopsInsuranceModel = new GadgetCopsInsuranceModel();
883
		gadgetCopsInsuranceModel.setBrand(brand);
884
		gadgetCopsInsuranceModel.setModelName(modelName);
885
		gadgetCopsInsuranceModel.setSerialNumber(serialNumber);
886
		gadgetCopsInsuranceModel.setCustomerFirstName(customer.getFirstName());
887
		gadgetCopsInsuranceModel.setCustomerLastName(customer.getLastName());
888
		gadgetCopsInsuranceModel.setCustomerDateOfBirth(customerDateOfBirth);
889
		gadgetCopsInsuranceModel.setCustomerMobileNumber(customer.getMobileNumber());
890
		gadgetCopsInsuranceModel.setCustomerEmailId(customer.getEmailId());
891
		gadgetCopsInsuranceModel.setCustomerAddress1(customerAddress.getLine1());
892
		gadgetCopsInsuranceModel.setCustomerAddress2(customerAddress.getLine2());
893
		gadgetCopsInsuranceModel.setCustomerCity(customerAddress.getCity());
894
		gadgetCopsInsuranceModel.setCustomerPinCode(customerAddress.getPinCode());
895
		gadgetCopsInsuranceModel.setCustomerState(customerAddress.getState());
896
		gadgetCopsInsuranceModel.setPrice(insurancePolicy.getSellingPrice());
897
		gadgetCopsInsuranceModel.setInvoiceNumber(insurancePolicy.getInvoiceNumber());
898
		gadgetCopsInsuranceModel.setPolicyNumber(insurancePolicy.getPolicyNumber());
899
		return gadgetCopsInsuranceModel;
900
	}
901
 
23394 amit.gupta 902
	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 903
		InsurancePolicy insurancePolicy = new InsurancePolicy();
23394 amit.gupta 904
		insurancePolicy.setInvoiceNumber(invoiceNumber);
22859 ashik.ali 905
		insurancePolicy.setRetailerId(retailerId);
906
		insurancePolicy.setPurchaseAmount(purchaseAmount);
907
		insurancePolicy.setSaleAmount(saleAmount);
908
		insurancePolicy.setSellingPrice(sellingPrice);
909
		insurancePolicy.setSerialNumber(serialNumber);
910
		insurancePolicy.setModelName(modelName);
911
		insurancePolicy.setBrand(brand);
912
		insurancePolicy.setPolicyNumber(StringUtils.generatePolicyNumber(ProfitMandiConstants.POLICY_NUMBER_PREFIX, policyNumberGenerationSequence));
913
		insurancePolicy.setProviderId(insuranceProviderId);
914
		insurancePolicy.setCustomerFirstName(customer.getFirstName());
915
		insurancePolicy.setCustomerLastName(customer.getLastName());
916
		insurancePolicy.setCustomerMobileNumber(customer.getMobileNumber());
917
		insurancePolicy.setCustomerEmailId(customer.getEmailId());
918
		insurancePolicy.setCustomerDateOfBirth(customerDateOfBirth);
919
		insurancePolicy.setCustomerAddress1(customerAddress.getLine1());
920
		insurancePolicy.setCustomerAddress2(customerAddress.getLine2());
921
		insurancePolicy.setCustomerCity(customerAddress.getCity());
922
		insurancePolicy.setCustomerPinCode(customerAddress.getPinCode());
923
		insurancePolicy.setCustomerState(customerAddress.getState());
924
		return insurancePolicy;
925
	}
926
 
22872 ashik.ali 927
	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 928
		Map<Float, Float> invalidInsuranceMarginAmount = new HashMap<>();
929
		for(Map.Entry<String, Float> entry : insuranceSerialNumberItemPrice.entrySet()){
22872 ashik.ali 930
			int itemId = this.getItemIdFromSerialNumber(itemIdCustomFofoOrderItemMap, entry.getKey());
22859 ashik.ali 931
			float itemPurchasePrice = itemIdMopPriceMap.get(itemId).getPrice();
932
			float itemSellingPrice = entry.getValue();
933
			float itemMargin = itemSellingPrice - itemPurchasePrice;
934
			float insurancePurchasePrice = insurancePricesMap.get(entry.getValue()).getDealerPrice();
935
			float insuranceSellingPrice = insuranceSerialNumberSaleAmount.get(entry.getKey());
936
			float insuranceMargin = insuranceSellingPrice - insurancePurchasePrice;
937
			if(insuranceMargin < (itemMargin * 30 / 100)){
938
				invalidInsuranceMarginAmount.put(insuranceMargin, (itemMargin * 30 / 100));
939
			}
940
		}
941
		if(!invalidInsuranceMarginAmount.isEmpty()){
942
			LOGGER.error("insurance marging should be greater than equal to item profit margin insuranceMarginItemIdMargin {}", invalidInsuranceMarginAmount);
22925 ashik.ali 943
			throw new ProfitMandiBusinessException("invalidInsuranceMarginAmount", invalidInsuranceMarginAmount, "FFORDR_1007");
22859 ashik.ali 944
		}
945
	}
946
 
947
	private void validateInsuranceAmount(Map<String, Float> insuranceSerialNumberItemPrice, Map<String, Float> insuranceSerialNumberSaleAmount, Map<Float, GadgetCopsInsuranceCalc> insurancePricesMap) throws ProfitMandiBusinessException{
948
		Map<Float, Float> invalidInsurancePurchaseSaleAmount = new HashMap<>();
949
		Map<Float, Float> invalidInsuranceSalePurchaseAmount = new HashMap<>();
950
		for(Map.Entry<String, Float> entry : insuranceSerialNumberItemPrice.entrySet()){
951
			if(insuranceSerialNumberSaleAmount.get(entry.getKey()) < insurancePricesMap.get(entry.getValue()).getDealerPrice()){
952
				invalidInsurancePurchaseSaleAmount.put(insurancePricesMap.get(entry.getValue()).getDealerPrice(), insuranceSerialNumberSaleAmount.get(entry.getKey()));
953
			}
954
 
955
			if(insuranceSerialNumberSaleAmount.get(entry.getKey()) > insurancePricesMap.get(entry.getValue()).getSellingPrice()){
956
				invalidInsuranceSalePurchaseAmount.put(insuranceSerialNumberSaleAmount.get(entry.getKey()), insurancePricesMap.get(entry.getValue()).getDealerPrice());
957
			}
958
		}
959
 
960
		// insurance sale amount can not be lesser than insurance purchase amount
961
		if(!invalidInsurancePurchaseSaleAmount.isEmpty()){
962
			LOGGER.error("Invalid Insurance prices [{}], insurance sale amount can not be lesser than insurance purchase amount", invalidInsurancePurchaseSaleAmount);
22925 ashik.ali 963
			throw new ProfitMandiBusinessException("invalidInsurancePurchaseSaleAmount", invalidInsurancePurchaseSaleAmount, "FFORDR_1008");
22859 ashik.ali 964
		}
965
 
966
		if(!invalidInsuranceSalePurchaseAmount.isEmpty()){
967
			LOGGER.error("Invalid Insurance prices [{}], insurance sale amount can not be greater than than insurance max amount", invalidInsuranceSalePurchaseAmount);
22925 ashik.ali 968
			throw new ProfitMandiBusinessException("invalidInsuranceSalePurchaseAmount", invalidInsuranceSalePurchaseAmount, "FFORDR_1009");
22859 ashik.ali 969
		}
970
	}
971
 
22872 ashik.ali 972
	private void validateMopPrice(Map<Integer, PriceModel> itemIdMopPriceMap, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException{
22859 ashik.ali 973
		Map<Integer, Float> invalidMopItemIdPriceMap = new HashMap<>();
974
		Map<Integer, Float> invalidDiscountAmountMap = new HashMap<>();
975
		//Map<Integer, PriceModel> itemIdMopPriceMap = pricingService.getPurchasePriceMopPriceNotFound(itemIds, fofoId);
976
		for(Map.Entry<Integer, PriceModel> entry : itemIdMopPriceMap.entrySet()){
22872 ashik.ali 977
			CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoLineItemMap.get(entry.getKey());
978
			if(entry.getValue().getPrice() < Float.MAX_VALUE && customFofoOrderItem.getSellingPrice() < entry.getValue().getPrice()){
979
				invalidMopItemIdPriceMap.put(entry.getKey(), customFofoOrderItem.getSellingPrice());
22859 ashik.ali 980
			}
22872 ashik.ali 981
			if(entry.getValue().isMop() && customFofoOrderItem.getDiscountAmount() > entry.getValue().getMaxDiscountAmount()){
982
				invalidDiscountAmountMap.put(entry.getKey(), customFofoOrderItem.getDiscountAmount());
983
			}
22859 ashik.ali 984
		}
985
 
986
		if(!invalidMopItemIdPriceMap.isEmpty()){
987
			LOGGER.error("Invalid itemIds selling prices{} should be greater than mop prices {}", invalidMopItemIdPriceMap, itemIdMopPriceMap);
22925 ashik.ali 988
			throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidMopItemIdPriceMap, "FFORDR_1010");
22859 ashik.ali 989
		}
990
 
991
		if(!invalidMopItemIdPriceMap.isEmpty()){
992
			LOGGER.error("Invalid itemIds discount amounts {} should be less than maxDiscount prices {}", invalidDiscountAmountMap, itemIdMopPriceMap);
22925 ashik.ali 993
			throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidDiscountAmountMap, "FFORDR_1011");
22859 ashik.ali 994
		}
995
	}
996
 
997
	private LocalDate validateCustomerDateOfBirth(String customerDateOfBirthString) throws ProfitMandiBusinessException{
998
		LocalDate customerDateOfBirth = null;
999
		try{
1000
			customerDateOfBirth = StringUtils.toDate(customerDateOfBirthString);
1001
		}catch(DateTimeException dateTimeException){
1002
			LOGGER.error("Unable to parse dateOfBirth", dateTimeException);
22925 ashik.ali 1003
			throw new ProfitMandiBusinessException("dateOfBirth", customerDateOfBirthString, "FFORDR_1012");
22859 ashik.ali 1004
		}
1005
		return customerDateOfBirth;
1006
	}
1007
 
1008
	private void updateInventoryItemsAndScanRecord(Set<InventoryItem> inventoryItems, int fofoId, Map<Integer, Integer> inventoryItemQuantityUsed){
1009
		for(InventoryItem inventoryItem : inventoryItems){
1010
			inventoryItem.setLastScanType(ScanType.SALE);
1011
			inventoryItemRepository.persist(inventoryItem);
1012
			ScanRecord scanRecord = new ScanRecord();
1013
			scanRecord.setInventoryItemId(inventoryItem.getId());
1014
			scanRecord.setFofoId(fofoId);
1015
			//correct this
1016
			scanRecord.setQuantity(inventoryItemQuantityUsed.get(inventoryItem.getId()));
1017
			scanRecord.setType(ScanType.SALE);
1018
			scanRecordRepository.persist(scanRecord);
1019
		}
1020
	}
1021
 
1022
	private void createFofoLineItem(int fofoOrderItemId, Set<InventoryItem> inventoryItems, Map<Integer, Integer> inventoryItemIdQuantityUsed){
1023
		for(InventoryItem inventoryItem : inventoryItems){
1024
			FofoLineItem fofoLineItem = new FofoLineItem();
1025
			fofoLineItem.setFofoOrderItemId(fofoOrderItemId);
1026
			fofoLineItem.setSerialNumber(inventoryItem.getSerialNumber());
1027
			fofoLineItem.setInventoryItemId(inventoryItem.getId());
1028
			fofoLineItem.setQuantity(inventoryItemIdQuantityUsed.get(inventoryItem.getId()));
1029
			fofoLineItemRepository.persist(fofoLineItem);
1030
		}
1031
	}
1032
 
23393 amit.gupta 1033
	private FofoOrderItem createAndGetFofoOrderItem(CustomFofoOrderItem customFofoOrderItem, int fofoOrderId, Map<Integer, Item> itemMap, Set<InventoryItem> inventoryItems, Integer stateId) throws ProfitMandiBusinessException{
22859 ashik.ali 1034
		FofoOrderItem fofoOrderItem = new FofoOrderItem();
1035
		fofoOrderItem.setItemId(customFofoOrderItem.getItemId());
1036
		fofoOrderItem.setQuantity(customFofoOrderItem.getQuantity());
1037
		fofoOrderItem.setSellingPrice(customFofoOrderItem.getSellingPrice());
1038
		fofoOrderItem.setOrderId(fofoOrderId);
1039
		fofoOrderItem.setDp(customFofoOrderItem.getSellingPrice());
1040
		fofoOrderItem.setDiscount(customFofoOrderItem.getDiscountAmount());
1041
		Item item = itemMap.get(customFofoOrderItem.getItemId());
23172 ashik.ali 1042
		Map<Integer, GstRate> itemIdStateTaxRateMap = null;
1043
		Map<Integer, Float> itemIdIgstTaxRateMap = null;
1044
		if(stateId != null){
1045
			itemIdStateTaxRateMap = Utils.getStateTaxRate(new ArrayList<>(itemMap.keySet()), stateId);
1046
		}else{
1047
			itemIdIgstTaxRateMap = Utils.getIgstTaxRate(new ArrayList<>(itemMap.keySet()));
1048
		}
23393 amit.gupta 1049
		float cost = 0;
22859 ashik.ali 1050
		for(InventoryItem inventoryItem : inventoryItems){
23172 ashik.ali 1051
			if(stateId == null){
1052
				fofoOrderItem.setIgstRate(itemIdIgstTaxRateMap.get(inventoryItem.getItemId()));
1053
			}else{
1054
				fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getCgstRate());
1055
				fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getSgstRate());
1056
			}
23418 ashik.ali 1057
 
22859 ashik.ali 1058
			fofoOrderItem.setHsnCode(inventoryItem.getHsnCode());
1059
			break;
1060
		}
23393 amit.gupta 1061
		for(InventoryItem inventoryItem : inventoryItems){
1062
			if(inventoryItem.getSerialNumber() != null) {
1063
				cost += inventoryItem.getUnitPrice() - inventoryItem.getPriceDropAmount();
1064
			} else {
1065
				cost += inventoryItem.getUnitPrice();
23382 amit.gupta 1066
			}
1067
		}
23393 amit.gupta 1068
		cost = cost/customFofoOrderItem.getQuantity();
23382 amit.gupta 1069
		fofoOrderItem.setCost(cost);
22859 ashik.ali 1070
		fofoOrderItem.setBrand(item.getBrand());
1071
		fofoOrderItem.setModelName(item.getModelName());
1072
		fofoOrderItem.setModelNumber(item.getModelNumber());
1073
		fofoOrderItem.setColor(item.getColor());
1074
		fofoOrderItemRepository.persist(fofoOrderItem);
1075
		return fofoOrderItem;
1076
	}
1077
 
1078
	private void updateCurrentInventorySnapshot(List<CurrentInventorySnapshot> currentInventorySnapshots, int fofoId, int itemId, int quantity) throws ProfitMandiBusinessException{
1079
		for(CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots){
1080
			if(currentInventorySnapshot.getItemId() == itemId && currentInventorySnapshot.getFofoId() == fofoId){
1081
				currentInventorySnapshotRepository.updateAvailabilityByItemIdAndFofoId(itemId, fofoId, currentInventorySnapshot.getAvailability() - quantity);
1082
			}
1083
		}
1084
	}
1085
 
23365 ashik.ali 1086
	private void createPaymentOptions(int fofoOrderId, Set<CustomPaymentOption> customPaymentOptions) throws ProfitMandiBusinessException{
22859 ashik.ali 1087
		for(CustomPaymentOption customPaymentOption : customPaymentOptions){
23371 ashik.ali 1088
			if(customPaymentOption.getAmount() > 0) {
1089
				FofoOrderPaymentOption fofoOrderPaymentOption = new FofoOrderPaymentOption();
1090
				fofoOrderPaymentOption.setFofoOrderId(fofoOrderId);
1091
				fofoOrderPaymentOption.setPaymentOptionId(customPaymentOption.getPaymentOptionId());
1092
				fofoOrderPaymentOption.setAmount(customPaymentOption.getAmount());
1093
				fofoOrderPaymentOptionRepository.persist(fofoOrderPaymentOption);
1094
			}
22859 ashik.ali 1095
		}
1096
	}
1097
 
23369 ashik.ali 1098
	private FofoOrder createAndGetFofoOrder(int customerId, String customerGstNumber, int fofoId, InvoiceNumberGenerationSequence invoiceNumberGenerationSequence, float totalAmount, int customerAddressId){
22859 ashik.ali 1099
		FofoOrder fofoOrder = new FofoOrder();
23369 ashik.ali 1100
		fofoOrder.setCustomerGstNumber(customerGstNumber);
22859 ashik.ali 1101
		fofoOrder.setCustomerId(customerId);
1102
		fofoOrder.setFofoId(fofoId);
23370 ashik.ali 1103
		fofoOrder.setInvoiceNumber(invoiceNumberGenerationSequence.getPrefix() + "/" + invoiceNumberGenerationSequence.getSequence());
22859 ashik.ali 1104
		fofoOrder.setTotalAmount(totalAmount);
1105
		fofoOrder.setCustomerAddressId(customerAddressId);
1106
		fofoOrderRepository.persist(fofoOrder);
1107
		return fofoOrder;
1108
	}
1109
 
1110
	private Customer createAndGetCustomer(CustomCustomer customCustomer) throws ProfitMandiBusinessException{
1111
		Customer customer = null;
1112
		try{
1113
			customer = customerRepository.selectByMobileNumber(customCustomer.getMobileNumber());
1114
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
1115
			LOGGER.error("Error : ", profitMandiBusinessException);
1116
			customer = new Customer();
1117
		}
23190 ashik.ali 1118
		customer.setFirstName(customCustomer.getFirstName());
1119
		customer.setLastName(customCustomer.getLastName());
1120
		customer.setEmailId(customCustomer.getEmailId());
1121
		customer.setMobileNumber(customCustomer.getMobileNumber());
1122
		customerRepository.persist(customer);
22859 ashik.ali 1123
		return customer;
1124
	}
1125
 
23202 ashik.ali 1126
	private InvoiceNumberGenerationSequence createAndGetInvoiceNumberGenerationSequence(int fofoId, String fofoStoreCode){
22859 ashik.ali 1127
		InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;
1128
		try{
1129
			invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);
1130
			invoiceNumberGenerationSequence.setSequence(invoiceNumberGenerationSequence.getSequence() + 1);
1131
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
1132
			invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();
1133
			invoiceNumberGenerationSequence.setFofoId(fofoId);
23370 ashik.ali 1134
			invoiceNumberGenerationSequence.setPrefix(fofoStoreCode);
22859 ashik.ali 1135
			invoiceNumberGenerationSequence.setSequence(1);
1136
		}
1137
		invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);
1138
		return invoiceNumberGenerationSequence;
1139
	}
1140
 
22872 ashik.ali 1141
	private void validateItemsSerializedNonSerialized(List<Item> items, Map<Integer, CustomFofoOrderItem> customFofoOrderItemMap) throws ProfitMandiBusinessException{
22859 ashik.ali 1142
 		List<Integer> invalidItemIdSerialNumbers = new ArrayList<Integer>();
1143
		List<Integer> itemIdNonSerializedSerialNumbers = new ArrayList<Integer>();
1144
		for (Item i : items){
22872 ashik.ali 1145
			CustomFofoOrderItem customFofoOrderItem = customFofoOrderItemMap.get(i.getId());
1146
			if (i.getType().equals(ItemType.SERIALIZED)){
1147
				if (customFofoOrderItem == null || customFofoOrderItem.getSerialNumberDetails().isEmpty()){
1148
					invalidItemIdSerialNumbers.add(i.getId());
22859 ashik.ali 1149
				}
23202 ashik.ali 1150
			}else{
23377 ashik.ali 1151
				Set<String> serialNumbers = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());
1152
				if (customFofoOrderItem == null || !serialNumbers.isEmpty()){
22872 ashik.ali 1153
					itemIdNonSerializedSerialNumbers.add(i.getId());
22859 ashik.ali 1154
				}
1155
			}
1156
		}
1157
 
1158
		if(!invalidItemIdSerialNumbers.isEmpty()){
1159
			LOGGER.error("Invalid itemId's serialNumbers for serialized{}", invalidItemIdSerialNumbers);
1160
			// itemId's are serialized you are saying these are not serialized
22925 ashik.ali 1161
			throw new ProfitMandiBusinessException("invalidItemIdSerialNumbers", invalidItemIdSerialNumbers, "FFORDR_1013");
22859 ashik.ali 1162
		}
1163
 
1164
		if(!itemIdNonSerializedSerialNumbers.isEmpty()){
1165
			LOGGER.error("Invalid itemId's serialNumbers for non serialized{}", itemIdNonSerializedSerialNumbers);
1166
			// itemId's are non serialized you are saying these are serialized
22925 ashik.ali 1167
			throw new ProfitMandiBusinessException("itemIdNonSerializedSerialNumbers", itemIdNonSerializedSerialNumbers, "FFORDR_1014");
22859 ashik.ali 1168
		}
1169
	}
1170
 
22872 ashik.ali 1171
	private void validateCurrentInventorySnapshotQuantities(List<CurrentInventorySnapshot> currentInventorySnapshots, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap) throws ProfitMandiBusinessException{
1172
		if(itemIdCustomFofoOrderItemMap.keySet().size() != currentInventorySnapshots.size()){
22859 ashik.ali 1173
			throw new ProfitMandiBusinessException("quantiiesSize", currentInventorySnapshots.size(), "");
1174
		}
1175
		List<ItemIdQuantityAvailability> itemIdQuantityAvailabilities = new ArrayList<>(); //this is for error
1176
		LOGGER.info("currentInventorySnapshots "+currentInventorySnapshots);
22872 ashik.ali 1177
		LOGGER.info("CustomFofoLineItemMap {}", itemIdCustomFofoOrderItemMap);
22859 ashik.ali 1178
		for(CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots){
22872 ashik.ali 1179
			CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoOrderItemMap.get(currentInventorySnapshot.getItemId());
1180
			LOGGER.info("customFofoOrderItem {}", customFofoOrderItem);
1181
			if(customFofoOrderItem.getQuantity() > currentInventorySnapshot.getAvailability()){
22859 ashik.ali 1182
					ItemIdQuantityAvailability itemIdQuantityAvailability = new ItemIdQuantityAvailability();
1183
					itemIdQuantityAvailability.setItemId(customFofoOrderItem.getItemId());
1184
					Quantity quantity = new Quantity();
1185
					quantity.setAvailable(currentInventorySnapshot.getAvailability());
1186
					quantity.setRequested(customFofoOrderItem.getQuantity());
1187
					itemIdQuantityAvailability.setQuantity(quantity);
1188
					itemIdQuantityAvailabilities.add(itemIdQuantityAvailability);
1189
				}
1190
		}
1191
 
1192
		if(!itemIdQuantityAvailabilities.isEmpty()){
1193
			// itemIdQuantity request is not valid
1194
			LOGGER.error("Requested quantities should not be greater than currently available quantities {}", itemIdQuantityAvailabilities);
22925 ashik.ali 1195
			throw new ProfitMandiBusinessException("itemIdQuantityAvailabilities", itemIdQuantityAvailabilities, "FFORDR_1015");
22859 ashik.ali 1196
		}
1197
	}
1198
 
22872 ashik.ali 1199
	private int getItemIdFromSerialNumber(Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap, String serialNumber){
1200
		int itemId = 0;
1201
		for(Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoOrderItemMap.entrySet()){
1202
			Set<SerialNumberDetail> serialNumberDetails = entry.getValue().getSerialNumberDetails();
1203
			for(SerialNumberDetail serialNumberDetail : serialNumberDetails){
1204
				if(serialNumberDetail.getSerialNumber().equals(serialNumber)){
1205
					itemId = entry.getKey();
1206
					break;
1207
				}
22859 ashik.ali 1208
			}
1209
		}
22872 ashik.ali 1210
		return itemId;
22859 ashik.ali 1211
	}
1212
 
1213
	private Map<Integer, Item> toItemMap(List<Item> items){
22955 ashik.ali 1214
		Function<Item, Integer> itemIdFunction = new Function<Item, Integer>() {
1215
			@Override
1216
			public Integer apply(Item item) {
1217
				return item.getId();
1218
			}
1219
		};
1220
		Function<Item, Item> itemFunction = new Function<Item, Item>() {
1221
			@Override
1222
			public Item apply(Item item) {
1223
				return item;
1224
			}
1225
		};
1226
		return items.stream().collect(Collectors.toMap(itemIdFunction, itemFunction));
22859 ashik.ali 1227
	}
1228
 
23190 ashik.ali 1229
	private void setCustomerAddress(CustomerAddress customerAddress, CustomAddress customAddress){
22859 ashik.ali 1230
		customerAddress.setName(customAddress.getName());
1231
		customerAddress.setLine1(customAddress.getLine1());
1232
		customerAddress.setLine2(customAddress.getLine2());
1233
		customerAddress.setLandmark(customAddress.getLandmark());
1234
		customerAddress.setCity(customAddress.getCity());
1235
		customerAddress.setPinCode(customAddress.getPinCode());
1236
		customerAddress.setState(customAddress.getState());
1237
		customerAddress.setCountry(customAddress.getCountry());
1238
		customerAddress.setPhoneNumber(customAddress.getPhoneNumber());
1239
	}
1240
 
1241
	private CustomAddress createCustomAddress(Address address){
1242
		CustomAddress customAddress = new CustomAddress();
1243
		customAddress.setName(address.getName());
1244
		customAddress.setLine1(address.getLine1());
1245
		customAddress.setLine2(address.getLine2());
1246
		customAddress.setLandmark(address.getLandmark());
1247
		customAddress.setCity(address.getCity());
1248
		customAddress.setPinCode(address.getPinCode());
1249
		customAddress.setState(address.getState());
1250
		customAddress.setCountry(address.getCountry());
1251
		customAddress.setPhoneNumber(address.getPhoneNumber());
1252
		return customAddress;
1253
	}
1254
 
1255
	private CustomAddress createCustomAddress(CustomerAddress customerAddress){
1256
		CustomAddress customAddress = new CustomAddress();
1257
		customAddress.setName(customerAddress.getName());
1258
		customAddress.setLine1(customerAddress.getLine1());
1259
		customAddress.setLine2(customerAddress.getLine2());
1260
		customAddress.setLandmark(customerAddress.getLandmark());
1261
		customAddress.setCity(customerAddress.getCity());
1262
		customAddress.setPinCode(customerAddress.getPinCode());
1263
		customAddress.setState(customerAddress.getState());
1264
		customAddress.setCountry(customerAddress.getCountry());
1265
		customAddress.setPhoneNumber(customerAddress.getPhoneNumber());
1266
		return customAddress;
1267
	}
1268
 
1269
	private void validatePaymentOptionsAndTotalAmount(Set<CustomPaymentOption> customPaymentOptions, float totalAmount) throws ProfitMandiBusinessException
1270
	{
23365 ashik.ali 1271
		Set<Integer> paymentOptionIds = new HashSet<>();
1272
 
22859 ashik.ali 1273
		float calculatedAmount = 0;
1274
		for(CustomPaymentOption customPaymentOption : customPaymentOptions){
23365 ashik.ali 1275
			paymentOptionIds.add(customPaymentOption.getPaymentOptionId());
1276
			calculatedAmount = calculatedAmount + customPaymentOption.getAmount();
22859 ashik.ali 1277
		}
1278
		if(calculatedAmount != totalAmount){
22863 ashik.ali 1279
			LOGGER.warn("Error occured while validating payment options amount[{}] != TotalAmount [{}]", calculatedAmount, totalAmount);
22925 ashik.ali 1280
			throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_CALCULATED_AMOUNT, calculatedAmount, "FFORDR_1016");
22859 ashik.ali 1281
		}
23365 ashik.ali 1282
 
1283
		List<Integer> foundPaymentOptionIds = paymentOptionRepository.selectIdsByIds(paymentOptionIds);
1284
		if(foundPaymentOptionIds.size() != paymentOptionIds.size()) {
1285
			paymentOptionIds.removeAll(foundPaymentOptionIds);
1286
			throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_ID, paymentOptionIds, "FFORDR_1017");
1287
		}
22859 ashik.ali 1288
	}
22925 ashik.ali 1289
 
1290
	@Override
1291
	public List<FofoOrderItem> getByOrderId(int orderId) throws ProfitMandiBusinessException {
1292
		List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(orderId);
1293
		if(!fofoOrderItems.isEmpty()){
1294
			List<FofoOrderItem> newFofoOrderItems = new ArrayList<>();
1295
			Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = this.toFofoOrderItemIdFofoLineItems(fofoOrderItems);
1296
			Iterator<FofoOrderItem> fofoOrderItemsIterator = fofoOrderItems.iterator();
1297
			while(fofoOrderItemsIterator.hasNext()){
1298
				FofoOrderItem fofoOrderItem = fofoOrderItemsIterator.next();
1299
				fofoOrderItem.setFofoLineItems(fofoOrderItemIdFofoLineItemsMap.get(fofoOrderItem.getId()));
1300
				newFofoOrderItems.add(fofoOrderItem);
1301
				fofoOrderItemsIterator.remove();
1302
			}
1303
			fofoOrderItems = newFofoOrderItems;
1304
		}
1305
		return fofoOrderItems;
1306
	}
1307
 
1308
	private Set<Integer> toFofoOrderItemIds(List<FofoOrderItem> fofoOrderItems){
22955 ashik.ali 1309
		Function<FofoOrderItem, Integer> fofoOrderItemToFofoOrderItemIdFunction = new Function<FofoOrderItem, Integer>() {
1310
			@Override
1311
			public Integer apply(FofoOrderItem fofoOrderItem) {
1312
				return fofoOrderItem.getId();
1313
			}
1314
		};
1315
		return fofoOrderItems.stream().map(fofoOrderItemToFofoOrderItemIdFunction).collect(Collectors.toSet());
22925 ashik.ali 1316
	}
1317
 
1318
	private Map<Integer, Set<FofoLineItem>> toFofoOrderItemIdFofoLineItems(List<FofoOrderItem> fofoOrderItems){
1319
		Set<Integer> fofoOrderItemIds = this.toFofoOrderItemIds(fofoOrderItems);
1320
		List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIds);
1321
		Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = new HashMap<>();
1322
		for(FofoLineItem fofoLineItem : fofoLineItems){
1323
			if(!fofoOrderItemIdFofoLineItemsMap.containsKey(fofoLineItem.getFofoOrderItemId())){
1324
				Set<FofoLineItem> fofoLineItems2 = new HashSet<>();
1325
				fofoLineItems2.add(fofoLineItem);
1326
				fofoOrderItemIdFofoLineItemsMap.put(fofoLineItem.getFofoOrderItemId(), fofoLineItems2);
1327
			}else{
1328
				fofoOrderItemIdFofoLineItemsMap.get(fofoLineItem.getFofoOrderItemId()).add(fofoLineItem);
1329
			}
1330
		}
1331
		return fofoOrderItemIdFofoLineItemsMap;
1332
	}
23418 ashik.ali 1333
 
1334
	private String getOtpString(){
1335
		Random rndm_method = new Random();
1336
		String numbers ="0123456789";
1337
		char[] otp = new char[5];
22859 ashik.ali 1338
 
23418 ashik.ali 1339
		for (int i = 0; i < 5; i++){
1340
			otp[i] = numbers.charAt(rndm_method.nextInt(numbers.length()));
1341
		}
1342
		return String.valueOf(otp);
1343
	}
1344
 
1345
	private void sendOtp(String otp_text, String phone, Map<Integer, Float> itemIdAdvanceAmount){
1346
		Map<Integer, String> itemIdDescriptionMap = inventoryService.getItemIdDescriptionMap(itemIdAdvanceAmount.keySet());
1347
		StringBuilder itemIdAdvanceAmountString = new StringBuilder();
1348
		int index = 0;
1349
		for(Map.Entry<Integer, Float> itemIdAdvanceAmountEntry : itemIdAdvanceAmount.entrySet()) {
1350
			itemIdAdvanceAmountString.append(itemIdDescriptionMap.get(itemIdAdvanceAmountEntry.getKey()));
1351
			itemIdAdvanceAmountString.append("'s Advance amount [");
1352
			itemIdAdvanceAmountString.append(itemIdAdvanceAmountEntry.getValue());
1353
			itemIdAdvanceAmountString.append("]");
1354
			if(index + 1 < itemIdAdvanceAmount.size()) {
1355
				itemIdAdvanceAmountString.append(", ");
1356
			}
1357
			index++;
1358
		}
1359
		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.";
1360
		String msg = java.text.MessageFormat.format(text, otp_text, itemIdAdvanceAmountString);
1361
		try {
1362
			Utils.sendSms(msg, phone);
1363
		} catch (URISyntaxException e) {
1364
			// TODO Auto-generated catch block
1365
			e.printStackTrace();
1366
		} catch (IOException e) {
1367
			// TODO Auto-generated catch block
1368
			e.printStackTrace();
1369
		}
1370
 
1371
	}
1372
 
1373
	@Override
1374
	public int generatePrebookingOrdersOtp(String customerEmailId, String customerMobileNumber, Map<Integer, Float> itemIdAdvanceAmount) throws ProfitMandiBusinessException {
1375
		if(!StringUtils.isValidEmailAddress(customerEmailId)){
1376
			LOGGER.error("invalid customer emailId {} ", customerEmailId);
1377
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EMAIL_ID, customerEmailId, "VE_1016");
1378
		}
1379
 
1380
		if(!StringUtils.isValidMobile(customerMobileNumber)){
1381
			LOGGER.error("invalid customer mobileNumber {} ", customerMobileNumber);
1382
			throw new ProfitMandiBusinessException(ProfitMandiConstants.MOBILE_NUMBER, customerMobileNumber, "VE_1071");
1383
		}
1384
 
1385
		List<Otp> otps = otpRepository.selectAllByEmailWithTime(customerEmailId);
1386
		String otp = null;
1387
		if (otps.size() >= 5){
1388
			throw new ProfitMandiBusinessException(ProfitMandiConstants.CUSTOMER_EMAIL_ID, customerEmailId, "FFORDR_1019");
1389
		}
1390
		if (!otps.isEmpty()){
1391
			if (otps.get(0).getCreatedOn().isAfter(LocalDateTime.now().minusMinutes(2))){
1392
				return otps.get(0).getId();
1393
			}else if(otps.get(0).getCreatedOn().isAfter(LocalDateTime.now().minusMinutes(10))){
1394
				otp = otps.get(0).getOtp();
1395
			}
1396
		}
1397
		if (otp == null || otp.isEmpty()){
1398
			otp = getOtpString();
1399
		}
1400
 
1401
		this.sendOtp(otp, customerMobileNumber, itemIdAdvanceAmount);
1402
 
1403
		Otp otp_bean = new Otp();
1404
		otp_bean.setEmail(customerEmailId);
1405
		otp_bean.setMobile(customerMobileNumber);
1406
		otp_bean.setOtp(otp);
1407
		otp_bean.setOtpType(OtpType.PREBOOKING_ORDER);
1408
		otp_bean.setCreatedOn(LocalDateTime.now());
1409
		otp_bean.setExpiryTimestamp(LocalDateTime.now().plusMinutes(10));
1410
		otpRepository.persist(otp_bean);
1411
 
1412
		return otp_bean.getId();
1413
	}
1414
 
1415
	@Override
1416
	public String validateOtp(String customerEmailId, String customerMobileNumber, int otpId, String otpValue)
1417
			throws ProfitMandiBusinessException {
1418
		Otp otp = otpRepository.selectByIdEmailIdMobileNumber(otpId, customerEmailId, customerMobileNumber);
1419
		otp.setTryCount(otp.getTryCount() + 1);
1420
		if (!otp.getOtp().equalsIgnoreCase(otpValue)){
1421
			throw new ProfitMandiBusinessException("otpValue", otpValue, "FFORDR_1020");
1422
		}
1423
		if (otp.isExpired() || otp.isVerified() || otp.getExpiryTimestamp().isBefore(LocalDateTime.now())){
1424
			throw new ProfitMandiBusinessException("otpValue", otpValue, "FFORDR_1021");
1425
		}
1426
		if (otp.getTryCount() >5){
1427
			throw new ProfitMandiBusinessException("otpValue", otpValue, "FFORDR_1022");
1428
		}
1429
		otp.setExpired(true);
1430
		otp.setVerified(true);
1431
		otpRepository.persist(otp);
1432
 
1433
		return ResponseCodeHolder.getMessage("FFORDR_OK_1002");
1434
	}
1435
 
22859 ashik.ali 1436
}