Subversion Repositories SmartDukaan

Rev

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