Subversion Repositories SmartDukaan

Rev

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

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