Subversion Repositories SmartDukaan

Rev

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