Subversion Repositories SmartDukaan

Rev

Rev 25686 | Rev 25724 | 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
 
23612 amit.gupta 478
		this.createPaymentOptions(fofoOrder, createOrderRequest.getPaymentOptions());
23650 amit.gupta 479
 
23172 ashik.ali 480
		int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoId);
23650 amit.gupta 481
 
23172 ashik.ali 482
		Address retailerAddress = addressRepository.selectById(retailerAddressId);
23650 amit.gupta 483
 
23172 ashik.ali 484
		Integer stateId = null;
23650 amit.gupta 485
		if (customerAddress.getState().equals(retailerAddress.getState())) {
486
			try {
23172 ashik.ali 487
				stateId = Long.valueOf(Utils.getStateInfo(customerAddress.getState()).getId()).intValue();
23650 amit.gupta 488
			} catch (Exception e) {
23172 ashik.ali 489
				LOGGER.error("Unable to get state rates");
490
			}
491
		}
23650 amit.gupta 492
 
493
		for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
494
			FofoOrderItem fofoOrderItem = this.createAndGetFofoOrderItem(customFofoOrderItem, fofoOrder.getId(),
495
					itemMap, inventoryItemsToBill.get(customFofoOrderItem.getItemId()), stateId);
496
 
22859 ashik.ali 497
			Set<InventoryItem> inventoryItems = inventoryItemsToBill.get(customFofoOrderItem.getItemId());
23650 amit.gupta 498
 
22859 ashik.ali 499
			this.createFofoLineItem(fofoOrderItem.getId(), inventoryItems, inventoryItemIdQuantityUsed);
23650 amit.gupta 500
 
501
			this.updateCurrentInventorySnapshot(currentInventorySnapshots, fofoId, customFofoOrderItem.getItemId(),
502
					customFofoOrderItem.getQuantity());
503
 
24275 amit.gupta 504
			this.updateInventoryItemsAndScanRecord(inventoryItems, fofoId, inventoryItemIdQuantityUsed,
505
					fofoOrder.getId());
22859 ashik.ali 506
		}
23650 amit.gupta 507
 
25647 tejbeer 508
		List<FofoOrderItem> fofoItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
509
 
510
		for (FofoOrderItem fofoItem : fofoItems) {
511
			Item orderItem = itemRepository.selectById(fofoItem.getItemId());
512
			if (orderItem.getCategoryId() == ProfitMandiConstants.MOBILE_CATEGORY_ID) {
513
				this.createAndGetHygieneData(fofoOrder.getId(), fofoOrder.getFofoId());
514
			}
515
		}
22859 ashik.ali 516
		// insurance calculation is insurance flag is enabled
24440 amit.gupta 517
		//
518
		if (!insuranceSerialNumberMap.isEmpty()) {
519
			LOGGER.info("Processing insurane for serialNumbers");
23650 amit.gupta 520
 
24440 amit.gupta 521
			LocalDate customerDateOfBirth = LocalDate.from(createOrderRequest.getCustomer().getDateOfBirth());
23650 amit.gupta 522
 
24440 amit.gupta 523
			for (Map.Entry<String, InsuranceModel> entry : insuranceSerialNumberMap.entrySet()) {
524
				InsuranceModel insuranceModel = entry.getValue();
525
				MobileInsurancePlan mobileInsurancePlan = zestService.getAllPlansMap()
526
						.get(insuranceModel.getInsuranceId());
527
				InsurancePolicy insurancePolicy = this.createInsurancePolicy(fofoOrder.getInvoiceNumber(), fofoId,
528
						insuranceModel.getInsuranceAmount() - mobileInsurancePlan.getPartnerCommission(),
529
						insuranceModel.getInsuranceAmount(), insuranceModel.getDeviceSellingPrice(), entry.getKey(),
530
						insuranceModel.getModelName(), insuranceModel.getBrand(), customer, customerDateOfBirth,
24823 amit.gupta 531
						customerAddress,
532
						mobileInsurancePlan.getProductName() + " for " + mobileInsurancePlan.getDuration() + " Months");
23650 amit.gupta 533
 
24440 amit.gupta 534
				String walletDescription = null;
535
				if (mobileInsurancePlan.getProviderId().equals("0")) {
536
					insurancePolicy.setProviderId(1);
537
					int policyNumberGenerationSequence = this.createPolicyNumberGenerationSequence().getSequence();
538
					insurancePolicy.setPolicyNumber(StringUtils.generatePolicyNumber(
539
							ProfitMandiConstants.POLICY_NUMBER_PREFIX, policyNumberGenerationSequence));
540
					GadgetCopsInsuranceModel gadgetCopsInsuranceModel = this.createGadgetCopsInsuranceModel(
541
							entry.getValue().getBrand(), entry.getValue().getModelName(), entry.getKey(),
542
							customerDateOfBirth, customer, customerAddress, insurancePolicy);
23650 amit.gupta 543
 
24440 amit.gupta 544
					try {
545
						InsuranceUtils.submitToGadgetCops(gadgetCopsInsuranceModel);
546
						insurancePolicy.setPosted(true);
547
						walletDescription = "Sale of " + insurancePolicy.getPolicyNumber() + " for "
548
								+ fofoOrder.getInvoiceNumber();
549
					} catch (ProfitMandiBusinessException profitMandiBusinessException) {
550
						LOGGER.info("Unable to submit insurance policy details to {}", insuranceModel.getProviderName(),
551
								profitMandiBusinessException);
552
						throw new ProfitMandiBusinessException("Insurance", mobileInsurancePlan.getProductName(),
553
								"Could not generate insurance for Gadget Cop");
554
					}
555
				} else {
556
					try {
557
						WiseAppInsuaranceModel wiseAppInsuaranceModel = this
558
								.createWiseAppInsuranceModel(mobileInsurancePlan, insurancePolicy, customCustomer);
559
						String wiseAppInsuranceCode = zestService.createInsurance(wiseAppInsuaranceModel);
560
						insurancePolicy.setPolicyNumber(wiseAppInsuranceCode);
561
						// TODO: remove hardcoding
562
						insurancePolicy.setProviderId(2);
563
						walletDescription = "Sale of " + insurancePolicy.getProductName() + " against "
564
								+ fofoOrder.getInvoiceNumber();
565
					} catch (ProfitMandiBusinessException pbe) {
566
						pbe.printStackTrace();
567
						throw new ProfitMandiBusinessException("Insurance", mobileInsurancePlan.getProductName(),
568
								pbe.getMessage());
569
					}
570
				}
23650 amit.gupta 571
				walletService.consumeAmountFromWallet(fofoId, insurancePolicy.getId(),
23395 amit.gupta 572
						WalletReferenceType.DAMAGE_PROTECTION, walletDescription, insurancePolicy.getPurchaseAmount());
22859 ashik.ali 573
				insurancePolicyRepository.persist(insurancePolicy);
574
			}
575
		}
25686 amit.gupta 576
		schemeService.processSchemeOut(fofoOrder.getId(), fofoId);
22859 ashik.ali 577
		return fofoOrder.getId();
578
	}
23650 amit.gupta 579
 
25640 tejbeer 580
	private HygieneData createAndGetHygieneData(int id, int fofoId) {
581
		HygieneData hygieneData = new HygieneData();
582
		hygieneData.setOrderId(id);
583
		hygieneData.setFofoId(fofoId);
584
		hygieneData.setCreatedTimestamp(LocalDateTime.now());
585
		hygieneDataRepository.persist(hygieneData);
586
 
587
		return hygieneData;
588
	}
589
 
24440 amit.gupta 590
	private WiseAppInsuaranceModel createWiseAppInsuranceModel(MobileInsurancePlan mobileInsurancePlan,
591
			InsurancePolicy insurancePolicy, CustomCustomer customer) throws ProfitMandiBusinessException {
592
		WiseAppInsuaranceModel wiseAppInsuranceModel = new WiseAppInsuaranceModel();
593
		CustomAddress address = customer.getAddress();
594
 
595
		String sAddress = (address.getLine1() + " " + address.getLine2()).replaceAll("  ", " ");
596
		wiseAppInsuranceModel.setAddress(sAddress);
597
		wiseAppInsuranceModel.setBrand(insurancePolicy.getBrand());
598
		wiseAppInsuranceModel.setBalanceType("4");
599
		wiseAppInsuranceModel.setProduct(mobileInsurancePlan.getProductId());
600
		wiseAppInsuranceModel
601
				.setName((insurancePolicy.getCustomerFirstName() + " " + insurancePolicy.getCustomerLastName()));
602
		wiseAppInsuranceModel.setCity(address.getCity());
603
		wiseAppInsuranceModel.setDob(StringUtils.toHyphenatedString(customer.getDateOfBirth()));
604
		wiseAppInsuranceModel.setDuration(mobileInsurancePlan.getDuration());
605
		wiseAppInsuranceModel.setPincode(address.getPinCode());
606
		wiseAppInsuranceModel.setEmail(customer.getEmailId());
24450 amit.gupta 607
		wiseAppInsuranceModel.setDeviceType(mobileInsurancePlan.getDeviceTypeId());
24440 amit.gupta 608
		wiseAppInsuranceModel.setImeiNo(insurancePolicy.getSerialNumber());
609
		wiseAppInsuranceModel.setPlanValue(String.valueOf(insurancePolicy.getSaleAmount()));
610
		wiseAppInsuranceModel.setRetailerId(zestService.getWiseAppPartnerCode(insurancePolicy.getRetailerId()));
611
		wiseAppInsuranceModel.setDuration(mobileInsurancePlan.getDuration());
612
		wiseAppInsuranceModel.setGender(customer.getGender());
613
		wiseAppInsuranceModel.setInvoiceNo(insurancePolicy.getInvoiceNumber());
614
		wiseAppInsuranceModel.setNumber(insurancePolicy.getCustomerMobileNumber());
615
		wiseAppInsuranceModel
616
				.setPurchaseDate(StringUtils.toHyphenatedString(insurancePolicy.getCreateTimestamp().toLocalDate()));
617
		wiseAppInsuranceModel.setModel(insurancePolicy.getModelName());
618
		wiseAppInsuranceModel.setHandSetValue(String.valueOf(insurancePolicy.getSellingPrice()));
619
		wiseAppInsuranceModel.setInsurerCompany(mobileInsurancePlan.getProviderId());
620
		return wiseAppInsuranceModel;
621
	}
622
 
24807 amit.gupta 623
	@Override
624
	public String getInvoiceNumber(int fofoId, String fofoStoreCode) {
24236 amit.gupta 625
		InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;
626
		try {
627
			invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);
628
			invoiceNumberGenerationSequence.setSequence(invoiceNumberGenerationSequence.getSequence() + 1);
629
		} catch (ProfitMandiBusinessException profitMandiBusinessException) {
630
			invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();
631
			invoiceNumberGenerationSequence.setFofoId(fofoId);
632
			invoiceNumberGenerationSequence.setPrefix(fofoStoreCode);
633
			invoiceNumberGenerationSequence.setSequence(1);
634
		}
635
		invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);
636
		return invoiceNumberGenerationSequence.getPrefix() + "/" + invoiceNumberGenerationSequence.getSequence();
637
	}
24275 amit.gupta 638
 
639
	private String getSecurityDepositNumber(int fofoId, String fofoStoreCode) {
24226 amit.gupta 640
		InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;
641
		try {
642
			invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);
24275 amit.gupta 643
			invoiceNumberGenerationSequence
644
					.setChallanNumberSequence(invoiceNumberGenerationSequence.getChallanNumberSequence() + 1);
24226 amit.gupta 645
		} catch (ProfitMandiBusinessException profitMandiBusinessException) {
646
			invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();
647
			invoiceNumberGenerationSequence.setFofoId(fofoId);
648
			invoiceNumberGenerationSequence.setPrefix(fofoStoreCode);
649
			invoiceNumberGenerationSequence.setChallanNumberSequence(1);
650
		}
651
		invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);
24275 amit.gupta 652
		return invoiceNumberGenerationSequence.getPrefix() + "/SEC"
653
				+ invoiceNumberGenerationSequence.getChallanNumberSequence();
24226 amit.gupta 654
	}
655
 
23650 amit.gupta 656
	private Set<String> serialNumberDetailsToSerialNumbers(Set<SerialNumberDetail> serialNumberDetails) {
23377 ashik.ali 657
		Set<String> serialNumbers = new HashSet<>();
23650 amit.gupta 658
		for (SerialNumberDetail serialNumberDetail : serialNumberDetails) {
659
			if (serialNumberDetail.getSerialNumber() != null && !serialNumberDetail.getSerialNumber().isEmpty()) {
23377 ashik.ali 660
				serialNumbers.add(serialNumberDetail.getSerialNumber());
661
			}
662
		}
663
		return serialNumbers;
664
	}
23650 amit.gupta 665
 
22859 ashik.ali 666
	@Override
23596 ashik.ali 667
	public PdfModel getInvoicePdfModel(int orderId) throws ProfitMandiBusinessException {
668
		FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(orderId);
669
		return this.getInvoicePdfModel(fofoOrder);
670
	}
23650 amit.gupta 671
 
672
	private PdfModel getInvoicePdfModel(FofoOrder fofoOrder) throws ProfitMandiBusinessException {
673
 
674
		List<PaymentOptionTransaction> paymentOptionTransactions = paymentOptionTransactionRepository
675
				.selectByReferenceIdAndType(fofoOrder.getId(), PaymentOptionReferenceType.ORDER);
676
 
23552 amit.gupta 677
		List<CustomPaymentOption> paymentOptions = new ArrayList<>();
678
 
22859 ashik.ali 679
		PdfModel pdfModel = new PdfModel();
24823 amit.gupta 680
		pdfModel.setCancelled(fofoOrder.getCancelledTimestamp() != null);
23650 amit.gupta 681
		for (PaymentOptionTransaction paymentOptionTransaction : paymentOptionTransactions) {
23552 amit.gupta 682
			CustomPaymentOption cpi = new CustomPaymentOption();
683
			cpi.setAmount(paymentOptionTransaction.getAmount());
23650 amit.gupta 684
			cpi.setPaymentOption(
685
					paymentOptionRepository.selectById(paymentOptionTransaction.getPaymentOptionId()).getName());
23558 amit.gupta 686
			paymentOptions.add(cpi);
23552 amit.gupta 687
		}
24215 amit.gupta 688
		List<FofoOrderItem> fofoOrderItems = this.getByOrderId(fofoOrder.getId());
689
 
690
		pdfModel.setTitle("Retailer Invoice");
24275 amit.gupta 691
		if (fofoOrderItems.stream().findAny().get().getHsnCode().equals("NOGST")) {
24215 amit.gupta 692
			pdfModel.setTitle("Security Deposit Receipt");
693
		}
23552 amit.gupta 694
		pdfModel.setPaymentOptions(paymentOptions);
24215 amit.gupta 695
		pdfModel.setAuther("SmartDukaan");
24400 amit.gupta 696
		pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));
23650 amit.gupta 697
 
22859 ashik.ali 698
		// insurance calculation
23650 amit.gupta 699
		List<InsurancePolicy> insurancePolicies = insurancePolicyRepository
700
				.selectByRetailerIdInvoiceNumber(fofoOrder.getFofoId(), fofoOrder.getInvoiceNumber());
22859 ashik.ali 701
		Set<CustomInsurancePolicy> customInsurancePolicies = new HashSet<>();
702
		final float totalInsuranceTaxRate = 18;
23650 amit.gupta 703
		for (InsurancePolicy insurancePolicy : insurancePolicies) {
22859 ashik.ali 704
			float taxableInsurancePrice = insurancePolicy.getSaleAmount() / (1 + totalInsuranceTaxRate / 100);
705
			CustomInsurancePolicy customInsurancePolicy = new CustomInsurancePolicy();
23650 amit.gupta 706
			customInsurancePolicy.setDescription("Damage Protection Plan for device IMEI #"
707
					+ insurancePolicy.getSerialNumber() + "\n Certificate No. " + insurancePolicy.getPolicyNumber());
22859 ashik.ali 708
			customInsurancePolicy.setHsnCode("998716");
709
			customInsurancePolicy.setRate(taxableInsurancePrice);
710
			customInsurancePolicy.setIgstRate(18);
23650 amit.gupta 711
			customInsurancePolicy.setIgstAmount(taxableInsurancePrice * 18 / 100);
22936 amit.gupta 712
			customInsurancePolicy.setCgstRate(9);
23650 amit.gupta 713
			customInsurancePolicy.setCgstAmount(taxableInsurancePrice * 9 / 100);
22859 ashik.ali 714
			customInsurancePolicy.setSgstRate(9);
23650 amit.gupta 715
			customInsurancePolicy.setSgstAmount(taxableInsurancePrice * 9 / 100);
22859 ashik.ali 716
			customInsurancePolicy.setNetAmount(insurancePolicy.getSaleAmount());
717
			customInsurancePolicies.add(customInsurancePolicy);
718
		}
719
		pdfModel.setInsurancePolicies(customInsurancePolicies);
23001 amit.gupta 720
		List<String> tncs = new ArrayList<>();
721
		tncs.add("I agree that goods received are in good working condition");
722
		tncs.add("Goods once sold cannot be exchanged or taken back");
723
		tncs.add("Warranty for the goods received by me is the responsibility of the manufacturer only.");
23650 amit.gupta 724
		if (pdfModel.getInsurancePolicies() != null && pdfModel.getInsurancePolicies().size() > 0) {
725
			tncs.add("Damage protection provided is the responisibility of Protection Provider only");
726
		}
23001 amit.gupta 727
		pdfModel.setTncs(tncs);
24275 amit.gupta 728
 
23655 amit.gupta 729
		pdfModel.setCustomer(getCustomCustomer(fofoOrder));
22859 ashik.ali 730
		pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
731
		pdfModel.setTotalAmount(fofoOrder.getTotalAmount());
23650 amit.gupta 732
 
23596 ashik.ali 733
		Retailer retailer = retailerRepository.selectById(fofoOrder.getFofoId());
22859 ashik.ali 734
		PrivateDealUser privateDealUser = null;
23650 amit.gupta 735
		try {
22859 ashik.ali 736
			privateDealUser = privateDealUserRepository.selectById(retailer.getId());
23650 amit.gupta 737
		} catch (ProfitMandiBusinessException profitMandiBusinessException) {
22859 ashik.ali 738
			LOGGER.error("Private Deal User not found : ", profitMandiBusinessException);
739
		}
23650 amit.gupta 740
 
22859 ashik.ali 741
		User user = userRepository.selectById(userAccountRepository.selectUserIdByRetailerId(retailer.getId()));
742
		CustomRetailer customRetailer = new CustomRetailer();
743
		customRetailer.setBusinessName(retailer.getName());
744
		customRetailer.setMobileNumber(user.getMobileNumber());
23650 amit.gupta 745
		// customRetailer.setTinNumber(retailer.getNumber());
746
		if (privateDealUser == null) {
22859 ashik.ali 747
			customRetailer.setGstNumber(null);
23650 amit.gupta 748
		} else {
749
			if (null != privateDealUser.getCounterId()) {
22859 ashik.ali 750
				Counter counter = counterRepository.selectById(privateDealUser.getCounterId());
751
				customRetailer.setGstNumber(counter.getGstin());
23650 amit.gupta 752
			} else {
22859 ashik.ali 753
				customRetailer.setGstNumber(null);
754
			}
755
		}
23650 amit.gupta 756
		Address retailerAddress = addressRepository
757
				.selectById(retailerRegisteredAddressRepository.selectAddressIdByRetailerId(retailer.getId()));
22859 ashik.ali 758
		customRetailer.setAddress(this.createCustomAddress(retailerAddress));
759
		pdfModel.setRetailer(customRetailer);
23650 amit.gupta 760
 
22859 ashik.ali 761
		Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();
23650 amit.gupta 762
		for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
22859 ashik.ali 763
			CustomOrderItem customFofoOrderItem = new CustomOrderItem();
23650 amit.gupta 764
			float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate()
765
					+ fofoOrderItem.getCgstRate();
22859 ashik.ali 766
			float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
767
			float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
23650 amit.gupta 768
 
22859 ashik.ali 769
			customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));
23650 amit.gupta 770
			customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " "
771
					+ fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
23377 ashik.ali 772
			Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());
23650 amit.gupta 773
			// LOGGER.info("serialNumbers {}", serialNumbers);
774
			// LOGGER.info("serialNumbers is empty {}", serialNumbers.isEmpty());
775
			if (!serialNumbers.isEmpty()) {
776
				customFofoOrderItem.setDescription(
777
						customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
23377 ashik.ali 778
			}
22859 ashik.ali 779
			customFofoOrderItem.setRate(taxableSellingPrice);
780
			customFofoOrderItem.setDiscount(taxableDiscountPrice);
781
			customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());
23650 amit.gupta 782
			customFofoOrderItem.setNetAmount(
783
					(fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * fofoOrderItem.getQuantity());
22859 ashik.ali 784
			float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
785
			float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
786
			float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
787
			customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
788
			customFofoOrderItem.setIgstAmount(igstAmount);
789
			customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
790
			customFofoOrderItem.setCgstAmount(cgstAmount);
791
			customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
792
			customFofoOrderItem.setSgstAmount(sgstAmount);
793
			customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
794
			customerFofoOrderItems.add(customFofoOrderItem);
795
		}
796
		pdfModel.setOrderItems(customerFofoOrderItems);
24917 tejbeer 797
		String partnerAddressStateCode = stateRepository.selectByName(pdfModel.getRetailer().getAddress().getState())
798
				.getCode();
799
		String customerAddressStateCode = stateRepository.selectByName(pdfModel.getCustomer().getAddress().getState())
800
				.getCode();
24854 amit.gupta 801
		pdfModel.setPartnerAddressStateCode(partnerAddressStateCode);
802
		pdfModel.setCustomerAddressStateCode(customerAddressStateCode);
22859 ashik.ali 803
		return pdfModel;
23650 amit.gupta 804
 
22859 ashik.ali 805
	}
23650 amit.gupta 806
 
23655 amit.gupta 807
	private CustomCustomer getCustomCustomer(FofoOrder fofoOrder) throws ProfitMandiBusinessException {
808
		Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
809
		CustomCustomer customCustomer = new CustomCustomer();
810
		customCustomer.setFirstName(customer.getFirstName());
811
		customCustomer.setLastName(customer.getLastName());
812
		customCustomer.setEmailId(customer.getEmailId());
813
		customCustomer.setMobileNumber(customer.getMobileNumber());
814
		customCustomer.setGstNumber(fofoOrder.getCustomerGstNumber());
815
		CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());
816
		customCustomer.setAddress(this.createCustomAddress(customerAddress));
817
		return customCustomer;
818
	}
819
 
23596 ashik.ali 820
	@Override
821
	public PdfModel getInvoicePdfModel(int fofoId, int orderId) throws ProfitMandiBusinessException {
822
		FofoOrder fofoOrder = fofoOrderRepository.selectByFofoIdAndOrderId(fofoId, orderId);
823
		return this.getInvoicePdfModel(fofoOrder);
824
	}
23650 amit.gupta 825
 
22859 ashik.ali 826
	public String getBillingAddress(CustomerAddress customerAddress) {
827
		StringBuilder address = new StringBuilder();
828
		if ((customerAddress.getLine1() != null) && (!customerAddress.getLine1().isEmpty())) {
829
			address.append(customerAddress.getLine1());
830
			address.append(", ");
831
		}
832
 
833
		if ((customerAddress.getLine2() != null) && (!customerAddress.getLine2().isEmpty())) {
834
			address.append(customerAddress.getLine2());
835
			address.append(", ");
836
		}
837
 
838
		if ((customerAddress.getLandmark() != null) && (!customerAddress.getLandmark().isEmpty())) {
839
			address.append(customerAddress.getLandmark());
840
			address.append(", ");
841
		}
842
 
843
		if ((customerAddress.getCity() != null) && (!customerAddress.getCity().isEmpty())) {
844
			address.append(customerAddress.getCity());
845
			address.append(", ");
846
		}
847
 
848
		if ((customerAddress.getState() != null) && (!customerAddress.getState().isEmpty())) {
849
			address.append(customerAddress.getState());
850
		}
851
 
852
		if ((customerAddress.getPinCode() != null) && (!customerAddress.getPinCode().isEmpty())) {
853
			address.append("- ");
854
			address.append(customerAddress.getPinCode());
855
		}
856
 
857
		return address.toString();
858
	}
23650 amit.gupta 859
 
22859 ashik.ali 860
	@Override
23650 amit.gupta 861
	public List<CartFofo> cartCheckout(String cartJson) throws ProfitMandiBusinessException {
862
		try {
22859 ashik.ali 863
			JSONObject cartObject = new JSONObject(cartJson);
864
			Iterator<?> keys = cartObject.keys();
23650 amit.gupta 865
 
22859 ashik.ali 866
			Set<Integer> itemIds = new HashSet<>();
867
			List<CartFofo> cartItems = new ArrayList<CartFofo>();
23650 amit.gupta 868
 
869
			while (keys.hasNext()) {
870
				String key = (String) keys.next();
871
				if (cartObject.get(key) instanceof JSONObject) {
22859 ashik.ali 872
					LOGGER.info(cartObject.get(key).toString());
873
				}
874
				CartFofo cf = new CartFofo();
875
				cf.setItemId(cartObject.getJSONObject(key).getInt("itemId"));
876
				cf.setQuantity(cartObject.getJSONObject(key).getInt("quantity"));
23650 amit.gupta 877
 
878
				if (cf.getQuantity() <= 0) {
22859 ashik.ali 879
					continue;
880
				}
881
				cartItems.add(cf);
882
				itemIds.add(cartObject.getJSONObject(key).getInt("itemId"));
883
			}
23650 amit.gupta 884
			Map<Integer, Item> itemMap = new HashMap<Integer, Item>();
885
			if (itemIds.size() > 0) {
22859 ashik.ali 886
				List<Item> items = itemRepository.selectByIds(itemIds);
23650 amit.gupta 887
				for (Item i : items) {
22859 ashik.ali 888
					itemMap.put(i.getId(), i);
889
				}
23650 amit.gupta 890
 
22859 ashik.ali 891
			}
23650 amit.gupta 892
			for (CartFofo cf : cartItems) {
22859 ashik.ali 893
				Item i = itemMap.get(cf.getItemId());
23650 amit.gupta 894
				if (i == null) {
22859 ashik.ali 895
					continue;
896
				}
23650 amit.gupta 897
				cf.setDisplayName(getValidName(i.getBrand()) + " " + getValidName(i.getModelName()) + " "
898
						+ getValidName(i.getModelNumber()) + " " + getValidName(i.getColor()).replaceAll("\\s+", " "));
22859 ashik.ali 899
				cf.setItemType(i.getType());
900
			}
901
			return cartItems;
23650 amit.gupta 902
		} catch (Exception e) {
22859 ashik.ali 903
			LOGGER.error("Unable to Prepare cart to place order...", e);
22925 ashik.ali 904
			throw new ProfitMandiBusinessException("cartData", cartJson, "FFORDR_1006");
22859 ashik.ali 905
		}
906
	}
23650 amit.gupta 907
 
23202 ashik.ali 908
	@Override
23650 amit.gupta 909
	public Map<String, Object> getSaleHistory(int fofoId, SearchType searchType, String searchValue,
23891 amit.gupta 910
			LocalDateTime startDate, LocalDateTime endDate, int offset, int limit) throws ProfitMandiBusinessException {
23202 ashik.ali 911
		long countItems = 0;
912
		List<FofoOrder> fofoOrders = new ArrayList<>();
23650 amit.gupta 913
 
914
		if (searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()) {
24275 amit.gupta 915
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, null, null,
916
					offset, limit);
917
			countItems = fofoOrderRepository.selectCountByCustomerMobileNumber(fofoId, searchValue, null, null);
23650 amit.gupta 918
		} else if (searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()) {
24275 amit.gupta 919
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, null, null, offset,
920
					limit);
23973 govind 921
			countItems = fofoOrderRepository.selectCountByCustomerName(fofoId, searchValue, null, null);
23650 amit.gupta 922
		} else if (searchType == SearchType.IMEI && !searchValue.isEmpty()) {
24275 amit.gupta 923
			fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, null, null, offset,
924
					limit);
23973 govind 925
			countItems = fofoOrderRepository.selectCountBySerialNumber(fofoId, searchValue, null, null);
23650 amit.gupta 926
		} else if (searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()) {
24275 amit.gupta 927
			fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, null, null, offset, limit);
928
			countItems = fofoOrderRepository.selectCountByItemName(fofoId, searchValue, null, null);
23953 amit.gupta 929
		} else if (searchType == SearchType.INVOICE_NUMBER && !searchValue.isEmpty()) {
930
			fofoOrders = Arrays.asList(fofoOrderRepository.selectByFofoIdAndInvoiceNumber(fofoId, searchValue));
931
			countItems = fofoOrders.size();
24275 amit.gupta 932
		} else if (searchType == SearchType.DATE_RANGE) {
23891 amit.gupta 933
			fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDate, endDate, offset, limit);
934
			countItems = fofoOrderRepository.selectCountByFofoId(fofoId, startDate, endDate);
23202 ashik.ali 935
		}
936
		Map<String, Object> map = new HashMap<>();
23650 amit.gupta 937
 
23202 ashik.ali 938
		map.put("saleHistories", fofoOrders);
939
		map.put("start", offset + 1);
940
		map.put("size", countItems);
941
		map.put("searchType", searchType);
23351 ashik.ali 942
		map.put("searchTypes", SearchType.values());
23891 amit.gupta 943
		map.put("startDate", startDate);
23973 govind 944
		map.put("searchValue", searchValue);
23891 amit.gupta 945
		map.put(ProfitMandiConstants.END_TIME, endDate);
23650 amit.gupta 946
		if (fofoOrders.size() < limit) {
23202 ashik.ali 947
			map.put("end", offset + fofoOrders.size());
23650 amit.gupta 948
		} else {
23202 ashik.ali 949
			map.put("end", offset + limit);
950
		}
951
		return map;
952
	}
953
 
954
	@Override
23650 amit.gupta 955
	public Map<String, Object> getSaleHistoryPaginated(int fofoId, SearchType searchType, String searchValue,
23891 amit.gupta 956
			LocalDateTime startDate, LocalDateTime endDate, int offset, int limit) throws ProfitMandiBusinessException {
23202 ashik.ali 957
		List<FofoOrder> fofoOrders = new ArrayList<>();
23650 amit.gupta 958
 
959
		if (searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()) {
23891 amit.gupta 960
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, startDate,
961
					endDate, offset, limit);
23650 amit.gupta 962
		} else if (searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()) {
24275 amit.gupta 963
			fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, startDate, endDate,
964
					offset, limit);
23650 amit.gupta 965
		} else if (searchType == SearchType.IMEI && !searchValue.isEmpty()) {
24275 amit.gupta 966
			fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, startDate, endDate,
967
					offset, limit);
23650 amit.gupta 968
		} else if (searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()) {
24275 amit.gupta 969
			fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, startDate, endDate, offset,
970
					limit);
971
 
972
		} else if (searchType == SearchType.DATE_RANGE) {
23891 amit.gupta 973
			fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDate, endDate, offset, limit);
23202 ashik.ali 974
		}
975
		Map<String, Object> map = new HashMap<>();
976
		map.put("saleHistories", fofoOrders);
23973 govind 977
		map.put("searchType", searchType);
978
		map.put("searchTypes", SearchType.values());
979
		map.put("startDate", startDate);
980
		map.put("searchValue", searchValue);
981
		map.put(ProfitMandiConstants.END_TIME, endDate);
23202 ashik.ali 982
		return map;
983
	}
23650 amit.gupta 984
 
985
	private String getFofoStoreCode(int fofoId) throws ProfitMandiBusinessException {
23202 ashik.ali 986
		FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
23370 ashik.ali 987
		return fofoStore.getCode();
23202 ashik.ali 988
	}
23650 amit.gupta 989
 
990
	private CustomerAddress createCustomerAddress(CustomAddress customAddress, int customerId) {
23191 ashik.ali 991
		CustomerAddress customerAddress = null;
23650 amit.gupta 992
		try {
993
			// CustomAddress customAddress = customCustomer.getAddress();
994
			customerAddress = customerAddressRepository.selectByParams(customAddress.getName(),
995
					customAddress.getLine1(), customAddress.getLine2(), customAddress.getLandmark(),
996
					customAddress.getCity(), customAddress.getPinCode(), customAddress.getState(),
997
					customAddress.getPhoneNumber(), customAddress.getCountry(), customerId);
998
		} catch (ProfitMandiBusinessException profitMandiBusinessException) {
23596 ashik.ali 999
			LOGGER.warn("Customer address not found with [{}]", customAddress);
23191 ashik.ali 1000
			customerAddress = new CustomerAddress();
1001
			this.setCustomerAddress(customerAddress, customAddress);
1002
			customerAddress.setCustomerId(customerId);
24466 amit.gupta 1003
			customerAddressRepository.persist(customerAddress);
23191 ashik.ali 1004
		}
1005
		return customerAddress;
1006
	}
23650 amit.gupta 1007
 
1008
	private String getValidName(String name) {
1009
		return name != null ? name : "";
22859 ashik.ali 1010
	}
23650 amit.gupta 1011
 
1012
	private Set<String> toSerialNumbers(Set<FofoLineItem> fofoLineItems) {
23377 ashik.ali 1013
		Set<String> serialNumbers = new HashSet<>();
23650 amit.gupta 1014
		for (FofoLineItem fofoLineItem : fofoLineItems) {
1015
			if (fofoLineItem.getSerialNumber() != null && !fofoLineItem.getSerialNumber().isEmpty()) {
23377 ashik.ali 1016
				serialNumbers.add(fofoLineItem.getSerialNumber());
22955 ashik.ali 1017
			}
23377 ashik.ali 1018
		}
1019
		return serialNumbers;
22859 ashik.ali 1020
	}
23650 amit.gupta 1021
 
1022
	private PolicyNumberGenerationSequence createPolicyNumberGenerationSequence() {
22859 ashik.ali 1023
		PolicyNumberGenerationSequence policyNumberGenerationSequence = null;
23650 amit.gupta 1024
		try {
22859 ashik.ali 1025
			policyNumberGenerationSequence = policyNumberGenerationSequenceRepository.select();
1026
			policyNumberGenerationSequence.setSequence(policyNumberGenerationSequence.getSequence() + 1);
1027
			policyNumberGenerationSequenceRepository.persist(policyNumberGenerationSequence);
23650 amit.gupta 1028
		} catch (ProfitMandiBusinessException profitMandiBusinessException) {
22859 ashik.ali 1029
			policyNumberGenerationSequence = new PolicyNumberGenerationSequence();
1030
			policyNumberGenerationSequence.setSequence(1);
1031
			policyNumberGenerationSequenceRepository.persist(policyNumberGenerationSequence);
1032
		}
1033
		return policyNumberGenerationSequence;
1034
	}
23650 amit.gupta 1035
 
1036
	private GadgetCopsInsuranceModel createGadgetCopsInsuranceModel(String brand, String modelName, String serialNumber,
1037
			LocalDate customerDateOfBirth, Customer customer, CustomerAddress customerAddress,
1038
			InsurancePolicy insurancePolicy) {
22859 ashik.ali 1039
		GadgetCopsInsuranceModel gadgetCopsInsuranceModel = new GadgetCopsInsuranceModel();
1040
		gadgetCopsInsuranceModel.setBrand(brand);
1041
		gadgetCopsInsuranceModel.setModelName(modelName);
1042
		gadgetCopsInsuranceModel.setSerialNumber(serialNumber);
1043
		gadgetCopsInsuranceModel.setCustomerFirstName(customer.getFirstName());
1044
		gadgetCopsInsuranceModel.setCustomerLastName(customer.getLastName());
1045
		gadgetCopsInsuranceModel.setCustomerDateOfBirth(customerDateOfBirth);
1046
		gadgetCopsInsuranceModel.setCustomerMobileNumber(customer.getMobileNumber());
1047
		gadgetCopsInsuranceModel.setCustomerEmailId(customer.getEmailId());
1048
		gadgetCopsInsuranceModel.setCustomerAddress1(customerAddress.getLine1());
1049
		gadgetCopsInsuranceModel.setCustomerAddress2(customerAddress.getLine2());
1050
		gadgetCopsInsuranceModel.setCustomerCity(customerAddress.getCity());
1051
		gadgetCopsInsuranceModel.setCustomerPinCode(customerAddress.getPinCode());
1052
		gadgetCopsInsuranceModel.setCustomerState(customerAddress.getState());
1053
		gadgetCopsInsuranceModel.setPrice(insurancePolicy.getSellingPrice());
1054
		gadgetCopsInsuranceModel.setInvoiceNumber(insurancePolicy.getInvoiceNumber());
1055
		gadgetCopsInsuranceModel.setPolicyNumber(insurancePolicy.getPolicyNumber());
1056
		return gadgetCopsInsuranceModel;
1057
	}
23650 amit.gupta 1058
 
1059
	private InsurancePolicy createInsurancePolicy(String invoiceNumber, int retailerId, float purchaseAmount,
1060
			float saleAmount, float sellingPrice, String serialNumber, String modelName, String brand,
24440 amit.gupta 1061
			Customer customer, LocalDate customerDateOfBirth, CustomerAddress customerAddress, String productName) {
22859 ashik.ali 1062
		InsurancePolicy insurancePolicy = new InsurancePolicy();
23394 amit.gupta 1063
		insurancePolicy.setInvoiceNumber(invoiceNumber);
22859 ashik.ali 1064
		insurancePolicy.setRetailerId(retailerId);
1065
		insurancePolicy.setPurchaseAmount(purchaseAmount);
1066
		insurancePolicy.setSaleAmount(saleAmount);
1067
		insurancePolicy.setSellingPrice(sellingPrice);
1068
		insurancePolicy.setSerialNumber(serialNumber);
1069
		insurancePolicy.setModelName(modelName);
1070
		insurancePolicy.setBrand(brand);
1071
		insurancePolicy.setCustomerFirstName(customer.getFirstName());
1072
		insurancePolicy.setCustomerLastName(customer.getLastName());
1073
		insurancePolicy.setCustomerMobileNumber(customer.getMobileNumber());
1074
		insurancePolicy.setCustomerEmailId(customer.getEmailId());
1075
		insurancePolicy.setCustomerDateOfBirth(customerDateOfBirth);
1076
		insurancePolicy.setCustomerAddress1(customerAddress.getLine1());
1077
		insurancePolicy.setCustomerAddress2(customerAddress.getLine2());
1078
		insurancePolicy.setCustomerCity(customerAddress.getCity());
1079
		insurancePolicy.setCustomerPinCode(customerAddress.getPinCode());
1080
		insurancePolicy.setCustomerState(customerAddress.getState());
24440 amit.gupta 1081
		insurancePolicy.setProductName(productName);
22859 ashik.ali 1082
		return insurancePolicy;
1083
	}
23650 amit.gupta 1084
 
23823 amit.gupta 1085
	private void validateDpPrice(Map<Integer, PriceModel> itemIdMopPriceMap,
1086
			Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException {
1087
		for (Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoLineItemMap.entrySet()) {
1088
			int itemId = entry.getKey();
1089
			CustomFofoOrderItem customFofoOrderItem = entry.getValue();
1090
			PriceModel priceModel = itemIdMopPriceMap.get(itemId);
25494 amit.gupta 1091
			if (customFofoOrderItem.getSerialNumberDetails().stream()
25499 amit.gupta 1092
					.filter(x -> org.apache.commons.lang.StringUtils.isNotEmpty(x.getSerialNumber()))
25494 amit.gupta 1093
					.collect(Collectors.toList()).size() > 0) {
24275 amit.gupta 1094
				if (priceModel.getPrice() > customFofoOrderItem.getSellingPrice()) {
25495 amit.gupta 1095
					throw new ProfitMandiBusinessException("Selling Price for ",
24275 amit.gupta 1096
							itemRepository.selectById(itemId).getItemDescription(), "FFORDR_1010");
23823 amit.gupta 1097
				}
1098
			} else {
24275 amit.gupta 1099
				if (priceModel.getPurchasePrice() > customFofoOrderItem.getSellingPrice()) {
1100
					throw new ProfitMandiBusinessException("Selling Price",
1101
							itemRepository.selectById(itemId).getItemDescription(),
1102
							"Selling Price should not be less than DP");
23823 amit.gupta 1103
				}
1104
			}
1105
		}
1106
	}
24275 amit.gupta 1107
 
23650 amit.gupta 1108
	private void validateMopPrice(Map<Integer, PriceModel> itemIdMopPriceMap,
1109
			Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException {
22859 ashik.ali 1110
		Map<Integer, Float> invalidMopItemIdPriceMap = new HashMap<>();
23650 amit.gupta 1111
		for (Map.Entry<Integer, PriceModel> entry : itemIdMopPriceMap.entrySet()) {
22872 ashik.ali 1112
			CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoLineItemMap.get(entry.getKey());
25102 amit.gupta 1113
			if (customFofoOrderItem.getSellingPrice() < entry.getValue().getPrice()) {
22872 ashik.ali 1114
				invalidMopItemIdPriceMap.put(entry.getKey(), customFofoOrderItem.getSellingPrice());
22859 ashik.ali 1115
			}
1116
		}
23650 amit.gupta 1117
 
1118
		if (!invalidMopItemIdPriceMap.isEmpty()) {
1119
			LOGGER.error("Invalid itemIds selling prices{} should be greater than mop prices {}",
1120
					invalidMopItemIdPriceMap, itemIdMopPriceMap);
22925 ashik.ali 1121
			throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidMopItemIdPriceMap, "FFORDR_1010");
22859 ashik.ali 1122
		}
23650 amit.gupta 1123
 
22859 ashik.ali 1124
	}
23650 amit.gupta 1125
 
1126
	private void updateInventoryItemsAndScanRecord(Set<InventoryItem> inventoryItems, int fofoId,
24264 amit.gupta 1127
			Map<Integer, Integer> inventoryItemQuantityUsed, int fofoOrderId) {
23650 amit.gupta 1128
		for (InventoryItem inventoryItem : inventoryItems) {
22859 ashik.ali 1129
			inventoryItem.setLastScanType(ScanType.SALE);
1130
			inventoryItemRepository.persist(inventoryItem);
1131
			ScanRecord scanRecord = new ScanRecord();
1132
			scanRecord.setInventoryItemId(inventoryItem.getId());
1133
			scanRecord.setFofoId(fofoId);
24264 amit.gupta 1134
			scanRecord.setOrderId(fofoOrderId);
23650 amit.gupta 1135
			// correct this
22859 ashik.ali 1136
			scanRecord.setQuantity(inventoryItemQuantityUsed.get(inventoryItem.getId()));
1137
			scanRecord.setType(ScanType.SALE);
1138
			scanRecordRepository.persist(scanRecord);
23566 amit.gupta 1139
			purchaseReturnItemRepository.deleteById(inventoryItem.getId());
23650 amit.gupta 1140
 
22859 ashik.ali 1141
		}
1142
	}
23650 amit.gupta 1143
 
1144
	private void createFofoLineItem(int fofoOrderItemId, Set<InventoryItem> inventoryItems,
1145
			Map<Integer, Integer> inventoryItemIdQuantityUsed) {
1146
		for (InventoryItem inventoryItem : inventoryItems) {
22859 ashik.ali 1147
			FofoLineItem fofoLineItem = new FofoLineItem();
1148
			fofoLineItem.setFofoOrderItemId(fofoOrderItemId);
1149
			fofoLineItem.setSerialNumber(inventoryItem.getSerialNumber());
1150
			fofoLineItem.setInventoryItemId(inventoryItem.getId());
1151
			fofoLineItem.setQuantity(inventoryItemIdQuantityUsed.get(inventoryItem.getId()));
1152
			fofoLineItemRepository.persist(fofoLineItem);
1153
		}
1154
	}
23650 amit.gupta 1155
 
1156
	private FofoOrderItem createAndGetFofoOrderItem(CustomFofoOrderItem customFofoOrderItem, int fofoOrderId,
1157
			Map<Integer, Item> itemMap, Set<InventoryItem> inventoryItems, Integer stateId)
1158
			throws ProfitMandiBusinessException {
22859 ashik.ali 1159
		FofoOrderItem fofoOrderItem = new FofoOrderItem();
1160
		fofoOrderItem.setItemId(customFofoOrderItem.getItemId());
1161
		fofoOrderItem.setQuantity(customFofoOrderItem.getQuantity());
1162
		fofoOrderItem.setSellingPrice(customFofoOrderItem.getSellingPrice());
1163
		fofoOrderItem.setOrderId(fofoOrderId);
25103 amit.gupta 1164
		TagListing tl = tagListingRepository.selectByItemId(customFofoOrderItem.getItemId());
25162 amit.gupta 1165
		// In case listing gets removed rebill it using the selling price
1166
		if (tl != null) {
25103 amit.gupta 1167
			fofoOrderItem.setDp(tl.getSellingPrice());
1168
		} else {
1169
			fofoOrderItem.setDp(customFofoOrderItem.getSellingPrice());
1170
		}
22859 ashik.ali 1171
		fofoOrderItem.setDiscount(customFofoOrderItem.getDiscountAmount());
24823 amit.gupta 1172
 
22859 ashik.ali 1173
		Item item = itemMap.get(customFofoOrderItem.getItemId());
23172 ashik.ali 1174
		Map<Integer, GstRate> itemIdStateTaxRateMap = null;
1175
		Map<Integer, Float> itemIdIgstTaxRateMap = null;
23650 amit.gupta 1176
		if (stateId != null) {
23172 ashik.ali 1177
			itemIdStateTaxRateMap = Utils.getStateTaxRate(new ArrayList<>(itemMap.keySet()), stateId);
23650 amit.gupta 1178
		} else {
23172 ashik.ali 1179
			itemIdIgstTaxRateMap = Utils.getIgstTaxRate(new ArrayList<>(itemMap.keySet()));
1180
		}
23650 amit.gupta 1181
		for (InventoryItem inventoryItem : inventoryItems) {
1182
			if (stateId == null) {
23172 ashik.ali 1183
				fofoOrderItem.setIgstRate(itemIdIgstTaxRateMap.get(inventoryItem.getItemId()));
23650 amit.gupta 1184
			} else {
23172 ashik.ali 1185
				fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getCgstRate());
1186
				fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getSgstRate());
1187
			}
23650 amit.gupta 1188
 
22859 ashik.ali 1189
			fofoOrderItem.setHsnCode(inventoryItem.getHsnCode());
1190
			break;
1191
		}
1192
		fofoOrderItem.setBrand(item.getBrand());
1193
		fofoOrderItem.setModelName(item.getModelName());
1194
		fofoOrderItem.setModelNumber(item.getModelNumber());
1195
		fofoOrderItem.setColor(item.getColor());
1196
		fofoOrderItemRepository.persist(fofoOrderItem);
1197
		return fofoOrderItem;
1198
	}
23650 amit.gupta 1199
 
1200
	private void updateCurrentInventorySnapshot(List<CurrentInventorySnapshot> currentInventorySnapshots, int fofoId,
1201
			int itemId, int quantity) throws ProfitMandiBusinessException {
1202
		for (CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {
1203
			if (currentInventorySnapshot.getItemId() == itemId && currentInventorySnapshot.getFofoId() == fofoId) {
1204
				currentInventorySnapshotRepository.updateAvailabilityByItemIdAndFofoId(itemId, fofoId,
1205
						currentInventorySnapshot.getAvailability() - quantity);
22859 ashik.ali 1206
			}
1207
		}
1208
	}
23650 amit.gupta 1209
 
1210
	private void createPaymentOptions(FofoOrder fofoOrder, Set<CustomPaymentOption> customPaymentOptions)
1211
			throws ProfitMandiBusinessException {
1212
		for (CustomPaymentOption customPaymentOption : customPaymentOptions) {
1213
			if (customPaymentOption.getAmount() > 0) {
23546 ashik.ali 1214
				PaymentOptionTransaction paymentOptionTransaction = new PaymentOptionTransaction();
23612 amit.gupta 1215
				paymentOptionTransaction.setReferenceId(fofoOrder.getId());
23546 ashik.ali 1216
				paymentOptionTransaction.setPaymentOptionId(customPaymentOption.getPaymentOptionId());
1217
				paymentOptionTransaction.setReferenceType(PaymentOptionReferenceType.ORDER);
1218
				paymentOptionTransaction.setAmount(customPaymentOption.getAmount());
23612 amit.gupta 1219
				paymentOptionTransaction.setFofoId(fofoOrder.getFofoId());
23546 ashik.ali 1220
				paymentOptionTransactionRepository.persist(paymentOptionTransaction);
23371 ashik.ali 1221
			}
22859 ashik.ali 1222
		}
1223
	}
23650 amit.gupta 1224
 
24275 amit.gupta 1225
	private FofoOrder createAndGetFofoOrder(int customerId, String customerGstNumber, int fofoId, String documentNumber,
1226
			float totalAmount, int customerAddressId) {
22859 ashik.ali 1227
		FofoOrder fofoOrder = new FofoOrder();
23369 ashik.ali 1228
		fofoOrder.setCustomerGstNumber(customerGstNumber);
22859 ashik.ali 1229
		fofoOrder.setCustomerId(customerId);
1230
		fofoOrder.setFofoId(fofoId);
24226 amit.gupta 1231
		fofoOrder.setInvoiceNumber(documentNumber);
22859 ashik.ali 1232
		fofoOrder.setTotalAmount(totalAmount);
1233
		fofoOrder.setCustomerAddressId(customerAddressId);
1234
		fofoOrderRepository.persist(fofoOrder);
1235
		return fofoOrder;
1236
	}
23650 amit.gupta 1237
 
1238
	private Customer createAndGetCustomer(CustomCustomer customCustomer) throws ProfitMandiBusinessException {
25169 amit.gupta 1239
		List<Customer> customers = customerRepository.selectAllByMobileNumber(customCustomer.getMobileNumber());
1240
		List<Customer> filtered = customers.stream()
1241
				.filter(x -> x.getEmailId().equals(customCustomer.getEmailId())
1242
						&& x.getFirstName().equals(customCustomer.getFirstName())
1243
						&& x.getLastName().equals(customCustomer.getLastName()))
1244
				.collect(Collectors.toList());
1245
		if (filtered.size() > 0) {
1246
			return filtered.get(0);
22859 ashik.ali 1247
		}
25169 amit.gupta 1248
		Customer customer = new Customer();
23190 ashik.ali 1249
		customer.setFirstName(customCustomer.getFirstName());
1250
		customer.setLastName(customCustomer.getLastName());
1251
		customer.setEmailId(customCustomer.getEmailId());
1252
		customer.setMobileNumber(customCustomer.getMobileNumber());
1253
		customerRepository.persist(customer);
22859 ashik.ali 1254
		return customer;
1255
	}
23650 amit.gupta 1256
 
1257
	private void validateItemsSerializedNonSerialized(List<Item> items,
1258
			Map<Integer, CustomFofoOrderItem> customFofoOrderItemMap) throws ProfitMandiBusinessException {
1259
		List<Integer> invalidItemIdSerialNumbers = new ArrayList<Integer>();
22859 ashik.ali 1260
		List<Integer> itemIdNonSerializedSerialNumbers = new ArrayList<Integer>();
23650 amit.gupta 1261
		for (Item i : items) {
22872 ashik.ali 1262
			CustomFofoOrderItem customFofoOrderItem = customFofoOrderItemMap.get(i.getId());
23650 amit.gupta 1263
			if (i.getType().equals(ItemType.SERIALIZED)) {
1264
				if (customFofoOrderItem == null || customFofoOrderItem.getSerialNumberDetails().isEmpty()) {
22872 ashik.ali 1265
					invalidItemIdSerialNumbers.add(i.getId());
22859 ashik.ali 1266
				}
23650 amit.gupta 1267
			} else {
1268
				Set<String> serialNumbers = this
1269
						.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());
1270
				if (customFofoOrderItem == null || !serialNumbers.isEmpty()) {
22872 ashik.ali 1271
					itemIdNonSerializedSerialNumbers.add(i.getId());
22859 ashik.ali 1272
				}
1273
			}
1274
		}
1275
 
23650 amit.gupta 1276
		if (!invalidItemIdSerialNumbers.isEmpty()) {
22859 ashik.ali 1277
			LOGGER.error("Invalid itemId's serialNumbers for serialized{}", invalidItemIdSerialNumbers);
1278
			// itemId's are serialized you are saying these are not serialized
23650 amit.gupta 1279
			throw new ProfitMandiBusinessException("invalidItemIdSerialNumbers", invalidItemIdSerialNumbers,
1280
					"FFORDR_1013");
22859 ashik.ali 1281
		}
1282
 
23650 amit.gupta 1283
		if (!itemIdNonSerializedSerialNumbers.isEmpty()) {
22859 ashik.ali 1284
			LOGGER.error("Invalid itemId's serialNumbers for non serialized{}", itemIdNonSerializedSerialNumbers);
1285
			// itemId's are non serialized you are saying these are serialized
23650 amit.gupta 1286
			throw new ProfitMandiBusinessException("itemIdNonSerializedSerialNumbers", itemIdNonSerializedSerialNumbers,
1287
					"FFORDR_1014");
22859 ashik.ali 1288
		}
1289
	}
23650 amit.gupta 1290
 
1291
	private void validateCurrentInventorySnapshotQuantities(List<CurrentInventorySnapshot> currentInventorySnapshots,
1292
			Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap) throws ProfitMandiBusinessException {
1293
		if (itemIdCustomFofoOrderItemMap.keySet().size() != currentInventorySnapshots.size()) {
22859 ashik.ali 1294
			throw new ProfitMandiBusinessException("quantiiesSize", currentInventorySnapshots.size(), "");
1295
		}
23650 amit.gupta 1296
		List<ItemIdQuantityAvailability> itemIdQuantityAvailabilities = new ArrayList<>(); // this is for error
1297
		LOGGER.info("currentInventorySnapshots " + currentInventorySnapshots);
22872 ashik.ali 1298
		LOGGER.info("CustomFofoLineItemMap {}", itemIdCustomFofoOrderItemMap);
23650 amit.gupta 1299
		for (CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {
1300
			CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoOrderItemMap
1301
					.get(currentInventorySnapshot.getItemId());
22872 ashik.ali 1302
			LOGGER.info("customFofoOrderItem {}", customFofoOrderItem);
23650 amit.gupta 1303
			if (customFofoOrderItem.getQuantity() > currentInventorySnapshot.getAvailability()) {
1304
				ItemIdQuantityAvailability itemIdQuantityAvailability = new ItemIdQuantityAvailability();
1305
				itemIdQuantityAvailability.setItemId(customFofoOrderItem.getItemId());
1306
				Quantity quantity = new Quantity();
1307
				quantity.setAvailable(currentInventorySnapshot.getAvailability());
1308
				quantity.setRequested(customFofoOrderItem.getQuantity());
1309
				itemIdQuantityAvailability.setQuantity(quantity);
1310
				itemIdQuantityAvailabilities.add(itemIdQuantityAvailability);
1311
			}
22859 ashik.ali 1312
		}
1313
 
23650 amit.gupta 1314
		if (!itemIdQuantityAvailabilities.isEmpty()) {
22859 ashik.ali 1315
			// itemIdQuantity request is not valid
23650 amit.gupta 1316
			LOGGER.error("Requested quantities should not be greater than currently available quantities {}",
1317
					itemIdQuantityAvailabilities);
1318
			throw new ProfitMandiBusinessException("itemIdQuantityAvailabilities", itemIdQuantityAvailabilities,
1319
					"FFORDR_1015");
22859 ashik.ali 1320
		}
1321
	}
23650 amit.gupta 1322
 
1323
	private int getItemIdFromSerialNumber(Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap,
1324
			String serialNumber) {
22872 ashik.ali 1325
		int itemId = 0;
23650 amit.gupta 1326
		for (Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoOrderItemMap.entrySet()) {
22872 ashik.ali 1327
			Set<SerialNumberDetail> serialNumberDetails = entry.getValue().getSerialNumberDetails();
23650 amit.gupta 1328
			for (SerialNumberDetail serialNumberDetail : serialNumberDetails) {
1329
				if (serialNumberDetail.getSerialNumber().equals(serialNumber)) {
22872 ashik.ali 1330
					itemId = entry.getKey();
1331
					break;
1332
				}
22859 ashik.ali 1333
			}
1334
		}
22872 ashik.ali 1335
		return itemId;
22859 ashik.ali 1336
	}
23650 amit.gupta 1337
 
1338
	private Map<Integer, Item> toItemMap(List<Item> items) {
22955 ashik.ali 1339
		Function<Item, Integer> itemIdFunction = new Function<Item, Integer>() {
1340
			@Override
1341
			public Integer apply(Item item) {
1342
				return item.getId();
1343
			}
1344
		};
1345
		Function<Item, Item> itemFunction = new Function<Item, Item>() {
1346
			@Override
1347
			public Item apply(Item item) {
1348
				return item;
1349
			}
1350
		};
1351
		return items.stream().collect(Collectors.toMap(itemIdFunction, itemFunction));
22859 ashik.ali 1352
	}
1353
 
23650 amit.gupta 1354
	private void setCustomerAddress(CustomerAddress customerAddress, CustomAddress customAddress) {
22859 ashik.ali 1355
		customerAddress.setName(customAddress.getName());
1356
		customerAddress.setLine1(customAddress.getLine1());
1357
		customerAddress.setLine2(customAddress.getLine2());
1358
		customerAddress.setLandmark(customAddress.getLandmark());
1359
		customerAddress.setCity(customAddress.getCity());
1360
		customerAddress.setPinCode(customAddress.getPinCode());
1361
		customerAddress.setState(customAddress.getState());
1362
		customerAddress.setCountry(customAddress.getCountry());
1363
		customerAddress.setPhoneNumber(customAddress.getPhoneNumber());
1364
	}
1365
 
23650 amit.gupta 1366
	private CustomAddress createCustomAddress(Address address) {
22859 ashik.ali 1367
		CustomAddress customAddress = new CustomAddress();
1368
		customAddress.setName(address.getName());
1369
		customAddress.setLine1(address.getLine1());
1370
		customAddress.setLine2(address.getLine2());
1371
		customAddress.setLandmark(address.getLandmark());
1372
		customAddress.setCity(address.getCity());
1373
		customAddress.setPinCode(address.getPinCode());
1374
		customAddress.setState(address.getState());
1375
		customAddress.setCountry(address.getCountry());
1376
		customAddress.setPhoneNumber(address.getPhoneNumber());
1377
		return customAddress;
1378
	}
1379
 
23650 amit.gupta 1380
	private CustomAddress createCustomAddress(CustomerAddress customerAddress) {
22859 ashik.ali 1381
		CustomAddress customAddress = new CustomAddress();
1382
		customAddress.setName(customerAddress.getName());
1383
		customAddress.setLine1(customerAddress.getLine1());
1384
		customAddress.setLine2(customerAddress.getLine2());
1385
		customAddress.setLandmark(customerAddress.getLandmark());
1386
		customAddress.setCity(customerAddress.getCity());
1387
		customAddress.setPinCode(customerAddress.getPinCode());
1388
		customAddress.setState(customerAddress.getState());
1389
		customAddress.setCountry(customerAddress.getCountry());
1390
		customAddress.setPhoneNumber(customerAddress.getPhoneNumber());
1391
		return customAddress;
1392
	}
1393
 
23650 amit.gupta 1394
	private void validatePaymentOptionsAndTotalAmount(Set<CustomPaymentOption> customPaymentOptions, float totalAmount)
1395
			throws ProfitMandiBusinessException {
23365 ashik.ali 1396
		Set<Integer> paymentOptionIds = new HashSet<>();
23650 amit.gupta 1397
 
22859 ashik.ali 1398
		float calculatedAmount = 0;
23650 amit.gupta 1399
		for (CustomPaymentOption customPaymentOption : customPaymentOptions) {
23365 ashik.ali 1400
			paymentOptionIds.add(customPaymentOption.getPaymentOptionId());
1401
			calculatedAmount = calculatedAmount + customPaymentOption.getAmount();
22859 ashik.ali 1402
		}
23650 amit.gupta 1403
		if (calculatedAmount != totalAmount) {
1404
			LOGGER.warn("Error occured while validating payment options amount[{}] != TotalAmount [{}]",
1405
					calculatedAmount, totalAmount);
1406
			throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_CALCULATED_AMOUNT,
1407
					calculatedAmount, "FFORDR_1016");
22859 ashik.ali 1408
		}
23650 amit.gupta 1409
 
23365 ashik.ali 1410
		List<Integer> foundPaymentOptionIds = paymentOptionRepository.selectIdsByIds(paymentOptionIds);
23650 amit.gupta 1411
		if (foundPaymentOptionIds.size() != paymentOptionIds.size()) {
23365 ashik.ali 1412
			paymentOptionIds.removeAll(foundPaymentOptionIds);
23650 amit.gupta 1413
			throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_ID, paymentOptionIds,
1414
					"FFORDR_1017");
23365 ashik.ali 1415
		}
22859 ashik.ali 1416
	}
23650 amit.gupta 1417
 
22925 ashik.ali 1418
	@Override
1419
	public List<FofoOrderItem> getByOrderId(int orderId) throws ProfitMandiBusinessException {
1420
		List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(orderId);
23650 amit.gupta 1421
		if (!fofoOrderItems.isEmpty()) {
22925 ashik.ali 1422
			List<FofoOrderItem> newFofoOrderItems = new ArrayList<>();
23650 amit.gupta 1423
			Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = this
1424
					.toFofoOrderItemIdFofoLineItems(fofoOrderItems);
22925 ashik.ali 1425
			Iterator<FofoOrderItem> fofoOrderItemsIterator = fofoOrderItems.iterator();
23650 amit.gupta 1426
			while (fofoOrderItemsIterator.hasNext()) {
22925 ashik.ali 1427
				FofoOrderItem fofoOrderItem = fofoOrderItemsIterator.next();
1428
				fofoOrderItem.setFofoLineItems(fofoOrderItemIdFofoLineItemsMap.get(fofoOrderItem.getId()));
1429
				newFofoOrderItems.add(fofoOrderItem);
1430
				fofoOrderItemsIterator.remove();
1431
			}
1432
			fofoOrderItems = newFofoOrderItems;
1433
		}
1434
		return fofoOrderItems;
1435
	}
23650 amit.gupta 1436
 
1437
	private Set<Integer> toFofoOrderItemIds(List<FofoOrderItem> fofoOrderItems) {
22955 ashik.ali 1438
		Function<FofoOrderItem, Integer> fofoOrderItemToFofoOrderItemIdFunction = new Function<FofoOrderItem, Integer>() {
1439
			@Override
1440
			public Integer apply(FofoOrderItem fofoOrderItem) {
1441
				return fofoOrderItem.getId();
1442
			}
1443
		};
1444
		return fofoOrderItems.stream().map(fofoOrderItemToFofoOrderItemIdFunction).collect(Collectors.toSet());
22925 ashik.ali 1445
	}
23650 amit.gupta 1446
 
1447
	private Map<Integer, Set<FofoLineItem>> toFofoOrderItemIdFofoLineItems(List<FofoOrderItem> fofoOrderItems) {
22925 ashik.ali 1448
		Set<Integer> fofoOrderItemIds = this.toFofoOrderItemIds(fofoOrderItems);
1449
		List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIds);
1450
		Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = new HashMap<>();
23650 amit.gupta 1451
		for (FofoLineItem fofoLineItem : fofoLineItems) {
1452
			if (!fofoOrderItemIdFofoLineItemsMap.containsKey(fofoLineItem.getFofoOrderItemId())) {
22925 ashik.ali 1453
				Set<FofoLineItem> fofoLineItems2 = new HashSet<>();
1454
				fofoLineItems2.add(fofoLineItem);
1455
				fofoOrderItemIdFofoLineItemsMap.put(fofoLineItem.getFofoOrderItemId(), fofoLineItems2);
23650 amit.gupta 1456
			} else {
22925 ashik.ali 1457
				fofoOrderItemIdFofoLineItemsMap.get(fofoLineItem.getFofoOrderItemId()).add(fofoLineItem);
1458
			}
1459
		}
1460
		return fofoOrderItemIdFofoLineItemsMap;
1461
	}
23650 amit.gupta 1462
 
23418 ashik.ali 1463
	@Override
23650 amit.gupta 1464
	public void updateCustomerDetails(CustomCustomer customCustomer, String invoiceNumber)
1465
			throws ProfitMandiBusinessException {
23582 ashik.ali 1466
		FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
1467
		Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
1468
		customer.setFirstName(customCustomer.getFirstName());
1469
		customer.setLastName(customCustomer.getLastName());
24121 govind 1470
		customer.setMobileNumber(customCustomer.getMobileNumber());
1471
		customer.setEmailId(customCustomer.getEmailId());
23582 ashik.ali 1472
		customerRepository.persist(customer);
1473
		CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());
25101 amit.gupta 1474
		if (!customerAddress.getState().equals(customCustomer.getAddress().getState())) {
1475
			List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
1476
			resetTaxation(fofoOrder.getFofoId(), customerAddress, fofoOrderItems);
1477
		}
23582 ashik.ali 1478
		this.setCustomerAddress(customerAddress, customCustomer.getAddress());
1479
		customerAddressRepository.persist(customerAddress);
24121 govind 1480
		fofoOrder.setCustomerGstNumber(customCustomer.getGstNumber());
23582 ashik.ali 1481
	}
23418 ashik.ali 1482
 
25101 amit.gupta 1483
	private void resetTaxation(int fofoId, CustomerAddress customerAddress, List<FofoOrderItem> fofoOrderItems)
1484
			throws ProfitMandiBusinessException {
1485
		int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoId);
1486
 
1487
		Address retailerAddress = addressRepository.selectById(retailerAddressId);
1488
 
1489
		Integer stateId = null;
1490
		if (customerAddress.getState().equals(retailerAddress.getState())) {
1491
			try {
1492
				stateId = Long.valueOf(Utils.getStateInfo(customerAddress.getState()).getId()).intValue();
1493
			} catch (Exception e) {
1494
				LOGGER.error("Unable to get state rates");
1495
			}
1496
		}
1497
		List<Integer> itemIds = fofoOrderItems.stream().map(x -> x.getItemId()).collect(Collectors.toList());
1498
		final Map<Integer, GstRate> gstRates;
1499
		if (stateId != null) {
1500
			gstRates = Utils.getStateTaxRate(itemIds, stateId);
1501
		} else {
1502
			gstRates = new HashMap<>();
1503
			Utils.getIgstTaxRate(itemIds).entrySet().forEach(x -> {
1504
				GstRate gstRate = new GstRate();
1505
				gstRate.setIgstRate(x.getValue());
1506
				gstRate.setCgstRate(0f);
1507
				gstRate.setSgstRate(0f);
1508
				gstRates.put(x.getKey(), gstRate);
1509
 
1510
			});
1511
		}
1512
		for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
1513
			GstRate rate = gstRates.get(fofoOrderItem.getItemId());
1514
			fofoOrderItem.setCgstRate(rate.getCgstRate());
1515
			fofoOrderItem.setSgstRate(rate.getSgstRate());
1516
			fofoOrderItem.setIgstRate(rate.getIgstRate());
1517
		}
1518
	}
1519
 
23638 amit.gupta 1520
	@Override
24275 amit.gupta 1521
	public CustomerCreditNote badReturn(int fofoId, FoiBadReturnRequest foiBadReturnRequest)
1522
			throws ProfitMandiBusinessException {
23655 amit.gupta 1523
		FofoOrderItem foi = fofoOrderItemRepository.selectById(foiBadReturnRequest.getFofoOrderItemId());
23650 amit.gupta 1524
		FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(foi.getOrderId());
23655 amit.gupta 1525
		if (fofoOrder.getFofoId() != fofoId) {
23638 amit.gupta 1526
			throw new ProfitMandiBusinessException("Partner Auth", "", "Invalid Order");
1527
		}
23655 amit.gupta 1528
		int billedQty = foi.getQuantity() - customerReturnItemRepository.selectAllByOrderItemId(foi.getId()).size();
24275 amit.gupta 1529
		if (foiBadReturnRequest.getMarkedBadArr().size() > billedQty) {
23655 amit.gupta 1530
			throw new ProfitMandiBusinessException("Cant bad return more than what is billed", "", "Invalid Quantity");
1531
		}
23650 amit.gupta 1532
		List<CustomerReturnItem> customerReturnItems = new ArrayList<>();
23655 amit.gupta 1533
		for (BadReturnRequest badReturnRequest : foiBadReturnRequest.getMarkedBadArr()) {
23650 amit.gupta 1534
			CustomerReturnItem customerReturnItem = new CustomerReturnItem();
1535
			customerReturnItem.setFofoId(fofoId);
23655 amit.gupta 1536
			customerReturnItem.setFofoOrderItemId(foiBadReturnRequest.getFofoOrderItemId());
24264 amit.gupta 1537
			customerReturnItem.setFofoOrderId(fofoOrder.getId());
23655 amit.gupta 1538
			customerReturnItem.setRemarks(badReturnRequest.getRemarks());
23650 amit.gupta 1539
			customerReturnItem.setInventoryItemId(badReturnRequest.getInventoryItemId());
1540
			customerReturnItem.setQuantity(1);
1541
			customerReturnItem.setType(ReturnType.BAD);
24275 amit.gupta 1542
			// customerReturnItemRepository.persist(customerReturnItem);
23650 amit.gupta 1543
			inventoryService.saleReturnInventoryItem(customerReturnItem);
1544
			customerReturnItems.add(customerReturnItem);
23638 amit.gupta 1545
		}
23655 amit.gupta 1546
		CustomerCreditNote creditNote = generateCreditNote(fofoOrder, customerReturnItems);
24275 amit.gupta 1547
		for (CustomerReturnItem customerReturnItem : customerReturnItems) {
1548
			purchaseReturnService.returnInventoryItem(fofoId, false, customerReturnItem.getInventoryItemId(),
1549
					ReturnType.BAD);
23655 amit.gupta 1550
		}
24275 amit.gupta 1551
		return creditNote;
23638 amit.gupta 1552
	}
1553
 
24275 amit.gupta 1554
	private CustomerCreditNote generateCreditNote(FofoOrder fofoOrder, List<CustomerReturnItem> customerReturnItems)
1555
			throws ProfitMandiBusinessException {
23650 amit.gupta 1556
 
23638 amit.gupta 1557
		InvoiceNumberGenerationSequence sequence = invoiceNumberGenerationSequenceRepository
23650 amit.gupta 1558
				.selectByFofoId(fofoOrder.getFofoId());
1559
		sequence.setCreditNoteSequence(sequence.getCreditNoteSequence() + 1);
23638 amit.gupta 1560
		invoiceNumberGenerationSequenceRepository.persist(sequence);
24275 amit.gupta 1561
 
23655 amit.gupta 1562
		String creditNoteNumber = sequence.getPrefix() + "/" + sequence.getCreditNoteSequence();
23650 amit.gupta 1563
		CustomerCreditNote creditNote = new CustomerCreditNote();
1564
		creditNote.setCreditNoteNumber(creditNoteNumber);
1565
		creditNote.setFofoId(fofoOrder.getFofoId());
23655 amit.gupta 1566
		creditNote.setFofoOrderId(fofoOrder.getId());
1567
		creditNote.setFofoOrderItemId(customerReturnItems.get(0).getFofoOrderItemId());
1568
		creditNote.setSettlementType(SettlementType.UNSETTLED);
23650 amit.gupta 1569
		customerCreditNoteRepository.persist(creditNote);
24275 amit.gupta 1570
 
23650 amit.gupta 1571
		for (CustomerReturnItem customerReturnItem : customerReturnItems) {
1572
			customerReturnItem.setCreditNoteId(creditNote.getId());
1573
			customerReturnItemRepository.persist(customerReturnItem);
23638 amit.gupta 1574
		}
24275 amit.gupta 1575
		// this.returnInventoryItems(inventoryItems, debitNote);
23638 amit.gupta 1576
 
23655 amit.gupta 1577
		return creditNote;
23650 amit.gupta 1578
	}
24275 amit.gupta 1579
 
23655 amit.gupta 1580
	@Override
1581
	public CreditNotePdfModel getCreditNotePdfModel(int customerCreditNoteId) throws ProfitMandiBusinessException {
1582
		CustomerCreditNote creditNote = customerCreditNoteRepository.selectById(customerCreditNoteId);
1583
		return getCreditNotePdfModel(creditNote);
1584
	}
24275 amit.gupta 1585
 
1586
	private CreditNotePdfModel getCreditNotePdfModel(CustomerCreditNote creditNote)
1587
			throws ProfitMandiBusinessException {
23655 amit.gupta 1588
		FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(creditNote.getFofoOrderId());
24275 amit.gupta 1589
		List<CustomerReturnItem> customerReturnItems = customerReturnItemRepository
1590
				.selectAllByCreditNoteId(creditNote.getId());
23655 amit.gupta 1591
		CustomCustomer customCustomer = getCustomCustomer(fofoOrder);
24275 amit.gupta 1592
 
23655 amit.gupta 1593
		Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();
24275 amit.gupta 1594
		CustomRetailer customRetailer = retailerService.getFofoRetailers(Arrays.asList(fofoOrder.getFofoId()))
1595
				.get(fofoOrder.getFofoId());
23655 amit.gupta 1596
 
1597
		FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(creditNote.getFofoOrderItemId());
1598
		float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
1599
		float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
1600
		float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
1601
 
1602
		CustomOrderItem customFofoOrderItem = new CustomOrderItem();
1603
		customFofoOrderItem.setAmount(customerReturnItems.size() * (taxableSellingPrice - taxableDiscountPrice));
1604
		customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " "
1605
				+ fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
24275 amit.gupta 1606
 
1607
		if (ItemType.SERIALIZED.equals(itemRepository.selectById(fofoOrderItem.getItemId()).getType())) {
23655 amit.gupta 1608
			Set<Integer> inventoryItemIds = customerReturnItems.stream().map(x -> x.getInventoryItemId())
1609
					.collect(Collectors.toSet());
1610
			List<String> serialNumbers = inventoryItemRepository.selectByIds(inventoryItemIds).stream()
1611
					.map(x -> x.getSerialNumber()).collect(Collectors.toList());
1612
			customFofoOrderItem.setDescription(
1613
					customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
1614
		}
24275 amit.gupta 1615
 
23655 amit.gupta 1616
		customFofoOrderItem.setRate(taxableSellingPrice);
1617
		customFofoOrderItem.setDiscount(taxableDiscountPrice);
1618
		customFofoOrderItem.setQuantity(customerReturnItems.size());
24275 amit.gupta 1619
		customFofoOrderItem.setNetAmount(
1620
				(fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * customFofoOrderItem.getQuantity());
23655 amit.gupta 1621
 
1622
		float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
1623
		float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
1624
		float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
1625
		LOGGER.info("fofoOrderItem - {}", fofoOrderItem);
1626
		customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
1627
		customFofoOrderItem.setIgstAmount(igstAmount);
1628
		customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
1629
		customFofoOrderItem.setCgstAmount(cgstAmount);
1630
		customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
1631
		customFofoOrderItem.setSgstAmount(sgstAmount);
1632
		customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
23721 amit.gupta 1633
		customFofoOrderItem.setOrderId(1);
23655 amit.gupta 1634
		customerFofoOrderItems.add(customFofoOrderItem);
24275 amit.gupta 1635
 
23650 amit.gupta 1636
		PdfModel pdfModel = new PdfModel();
1637
		pdfModel.setAuther("NSSPL");
23655 amit.gupta 1638
		pdfModel.setCustomer(customCustomer);
1639
		pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
1640
		pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));
1641
		pdfModel.setTitle("Credit Note");
1642
		pdfModel.setRetailer(customRetailer);
1643
		pdfModel.setTotalAmount(customFofoOrderItem.getNetAmount());
1644
		pdfModel.setOrderItems(customerFofoOrderItems);
24275 amit.gupta 1645
 
23650 amit.gupta 1646
		CreditNotePdfModel creditNotePdfModel = new CreditNotePdfModel();
1647
		creditNotePdfModel.setCreditNoteDate(FormattingUtils.formatDate(creditNote.getCreateTimestamp()));
1648
		creditNotePdfModel.setCreditNoteNumber(creditNote.getCreditNoteNumber());
1649
		creditNotePdfModel.setPdfModel(pdfModel);
1650
		return creditNotePdfModel;
1651
	}
23638 amit.gupta 1652
 
24275 amit.gupta 1653
	// This will remove the order and maintain order record and reverse inventory
1654
	// and scheme
24264 amit.gupta 1655
	@Override
1656
	public void cancelOrder(List<String> invoiceNumbers) throws Exception {
24275 amit.gupta 1657
		for (String invoiceNumber : invoiceNumbers) {
24264 amit.gupta 1658
			FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);
1659
			fofoOrder.setCancelledTimestamp(LocalDateTime.now());
1660
			fofoOrderRepository.persist(fofoOrder);
24275 amit.gupta 1661
			List<PaymentOptionTransaction> paymentTransactions = paymentOptionTransactionRepository
1662
					.selectByReferenceIdAndType(fofoOrder.getId(), PaymentOptionReferenceType.ORDER);
24264 amit.gupta 1663
			for (PaymentOptionTransaction paymentOptionTransaction : paymentTransactions) {
1664
				paymentOptionTransactionRepository.delete(paymentOptionTransaction);
1665
			}
1666
			List<FofoOrderItem> fois = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
1667
			List<InventoryItem> inventoryItems = new ArrayList<>();
24275 amit.gupta 1668
			fois.stream().forEach(x -> {
1669
				x.getFofoLineItems().stream().forEach(y -> {
24264 amit.gupta 1670
					inventoryService.rollbackInventory(y.getInventoryItemId(), y.getQuantity(), fofoOrder.getFofoId());
1671
					inventoryItems.add(inventoryItemRepository.selectById(y.getInventoryItemId()));
1672
				});
1673
			});
1674
			String reversalReason = "Order Rolledback/Cancelled for Invoice Number " + invoiceNumber;
1675
			schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, SchemeType.OUT);
1676
		}
1677
	}
1678
 
24271 amit.gupta 1679
	@Override
1680
	public float getSales(int fofoId, LocalDateTime startDate, LocalDateTime endDate) {
24287 amit.gupta 1681
		Float sales = fofoOrderRepository.selectSaleSumGroupByFofoIds(startDate, endDate).get(fofoId);
24285 amit.gupta 1682
		return sales == null ? 0f : sales;
24271 amit.gupta 1683
	}
1684
 
1685
	@Override
1686
	public float getSales(int fofoId, LocalDate onDate) {
24285 amit.gupta 1687
		LocalDateTime startTime = LocalDateTime.of(onDate, LocalTime.MIDNIGHT);
1688
		LocalDateTime endTime = LocalDateTime.of(onDate, LocalTime.MIDNIGHT).plusDays(1);
1689
		return this.getSales(fofoId, startTime, endTime);
24271 amit.gupta 1690
	}
1691
 
1692
	@Override
1693
	public float getSales(LocalDateTime onDate) {
1694
		// TODO Auto-generated method stub
1695
		return 0;
1696
	}
1697
 
1698
	@Override
1699
	public float getSales(LocalDateTime startDate, LocalDateTime endDate) {
1700
		// TODO Auto-generated method stub
1701
		return 0;
1702
	}
1703
 
24917 tejbeer 1704
	@Override
1705
	public boolean notifyColorChange(int orderId, int itemId) throws ProfitMandiBusinessException {
1706
		Order order = orderRepository.selectById(orderId);
25714 tejbeer 1707
		inventoryService.reservationCount(itemId, order);
25101 amit.gupta 1708
 
1709
		order.getLineItem().setItemId(itemId);
1710
		Item item = itemRepository.selectById(itemId);
24917 tejbeer 1711
		order.getLineItem().setColor(item.getColor());
1712
		return true;
1713
	}
1714
 
25083 amit.gupta 1715
	@Override
1716
	public FofoOrder getOrderByInventoryItemId(int inventoryItemId) throws Exception {
1717
		List<FofoLineItem> lineItems = fofoLineItemRepository.selectByInventoryItemId(inventoryItemId);
25101 amit.gupta 1718
		if (lineItems.size() > 0) {
25083 amit.gupta 1719
			FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(lineItems.get(0).getFofoOrderItemId());
1720
			fofoOrderItem.setFofoLineItems(new HashSet<>(lineItems));
1721
			FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(fofoOrderItem.getOrderId());
1722
			fofoOrder.setOrderItem(fofoOrderItem);
1723
			return fofoOrder;
1724
		} else {
1725
			throw new Exception(String.format("Could not find inventoryItemId - %s", inventoryItemId));
1726
		}
1727
	}
1728
 
22859 ashik.ali 1729
}