Subversion Repositories SmartDukaan

Rev

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