Subversion Repositories SmartDukaan

Rev

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