Subversion Repositories SmartDukaan

Rev

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