Subversion Repositories SmartDukaan

Rev

Rev 24271 | Rev 24285 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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