Subversion Repositories SmartDukaan

Rev

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