Subversion Repositories SmartDukaan

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
22925 ashik.ali 1
package com.spice.profitmandi.service.inventory;
22859 ashik.ali 2
 
3
import java.time.DateTimeException;
4
import java.time.LocalDate;
5
import java.util.ArrayList;
6
import java.util.HashMap;
7
import java.util.HashSet;
8
import java.util.Iterator;
9
import java.util.List;
10
import java.util.Map;
11
import java.util.Set;
12
 
13
import org.json.JSONObject;
14
import org.slf4j.Logger;
15
import org.slf4j.LoggerFactory;
16
import org.springframework.beans.factory.annotation.Autowired;
17
import org.springframework.stereotype.Component;
18
 
19
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
20
import com.spice.profitmandi.common.model.CartFofo;
21
import com.spice.profitmandi.common.model.CreateOrderRequest;
22
import com.spice.profitmandi.common.model.CustomAddress;
23
import com.spice.profitmandi.common.model.CustomCustomer;
24
import com.spice.profitmandi.common.model.CustomFofoOrderItem;
25
import com.spice.profitmandi.common.model.CustomInsurancePolicy;
26
import com.spice.profitmandi.common.model.CustomOrderItem;
27
import com.spice.profitmandi.common.model.CustomPaymentOption;
28
import com.spice.profitmandi.common.model.CustomRetailer;
29
import com.spice.profitmandi.common.model.GadgetCopsInsuranceModel;
30
import com.spice.profitmandi.common.model.ItemIdQuantityAvailability;
31
import com.spice.profitmandi.common.model.PdfModel;
32
import com.spice.profitmandi.common.model.PriceModel;
33
import com.spice.profitmandi.common.model.ProfitMandiConstants;
34
import com.spice.profitmandi.common.model.Quantity;
35
import com.spice.profitmandi.common.model.SerialNumberDetail;
36
import com.spice.profitmandi.common.util.InsuranceUtils;
37
import com.spice.profitmandi.common.util.StringUtils;
38
import com.spice.profitmandi.dao.entity.catalog.Item;
39
import com.spice.profitmandi.dao.entity.dtr.GadgetCopsInsuranceCalc;
40
import com.spice.profitmandi.dao.entity.dtr.InsurancePolicy;
41
import com.spice.profitmandi.dao.entity.dtr.InsuranceProvider;
42
import com.spice.profitmandi.dao.entity.dtr.PolicyNumberGenerationSequence;
43
import com.spice.profitmandi.dao.entity.dtr.Retailer;
44
import com.spice.profitmandi.dao.entity.dtr.User;
45
import com.spice.profitmandi.dao.entity.fofo.CurrentInventorySnapshot;
46
import com.spice.profitmandi.dao.entity.fofo.Customer;
47
import com.spice.profitmandi.dao.entity.fofo.CustomerAddress;
48
import com.spice.profitmandi.dao.entity.fofo.FofoLineItem;
49
import com.spice.profitmandi.dao.entity.fofo.FofoOrder;
50
import com.spice.profitmandi.dao.entity.fofo.FofoOrderItem;
51
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
52
import com.spice.profitmandi.dao.entity.fofo.InvoiceNumberGenerationSequence;
53
import com.spice.profitmandi.dao.entity.fofo.PaymentOption;
54
import com.spice.profitmandi.dao.entity.fofo.ScanRecord;
55
import com.spice.profitmandi.dao.entity.user.Address;
56
import com.spice.profitmandi.dao.entity.user.Counter;
57
import com.spice.profitmandi.dao.entity.user.PrivateDealUser;
58
import com.spice.profitmandi.dao.enumuration.fofo.PaymentOptionType;
59
import com.spice.profitmandi.dao.enumuration.fofo.ScanType;
60
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
61
import com.spice.profitmandi.dao.repository.dtr.InsurancePolicyRepository;
62
import com.spice.profitmandi.dao.repository.dtr.InsuranceProviderRepository;
63
import com.spice.profitmandi.dao.repository.dtr.PolicyNumberGenerationSequenceRepository;
64
import com.spice.profitmandi.dao.repository.dtr.RetailerRegisteredAddressRepository;
65
import com.spice.profitmandi.dao.repository.dtr.RetailerRepository;
66
import com.spice.profitmandi.dao.repository.dtr.UserAccountRepository;
67
import com.spice.profitmandi.dao.repository.dtr.UserRepository;
68
import com.spice.profitmandi.dao.repository.fofo.CurrentInventorySnapshotRepository;
69
import com.spice.profitmandi.dao.repository.fofo.CustomerAddressRepository;
70
import com.spice.profitmandi.dao.repository.fofo.CustomerRepository;
71
import com.spice.profitmandi.dao.repository.fofo.FofoLineItemRepository;
72
import com.spice.profitmandi.dao.repository.fofo.FofoOrderItemRepository;
73
import com.spice.profitmandi.dao.repository.fofo.FofoOrderRepository;
74
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
75
import com.spice.profitmandi.dao.repository.fofo.InvoiceNumberGenerationSequenceRepository;
76
import com.spice.profitmandi.dao.repository.fofo.PaymentOptionRepository;
77
import com.spice.profitmandi.dao.repository.fofo.ScanRecordRepository;
78
import com.spice.profitmandi.dao.repository.user.AddressRepository;
79
import com.spice.profitmandi.dao.repository.user.CounterRepository;
80
import com.spice.profitmandi.dao.repository.user.PrivateDealUserRepository;
81
import com.spice.profitmandi.service.pricing.PricingService;
82
import com.spice.profitmandi.service.scheme.SchemeService;
83
 
84
import in.shop2020.model.v1.catalog.ItemType;
85
 
86
@Component
87
public class OrderServiceImpl implements OrderService {
88
 
89
	private static final Logger LOGGER = LoggerFactory.getLogger(OrderServiceImpl.class);
90
 
91
	@Autowired
92
	private InventoryItemRepository inventoryItemRepository;
93
 
94
	@Autowired
95
	private CurrentInventorySnapshotRepository currentInventorySnapshotRepository;
96
 
97
	@Autowired
98
	private InvoiceNumberGenerationSequenceRepository invoiceNumberGenerationSequenceRepository;
99
 
100
	@Autowired
101
	private CustomerRepository customerRepository;
102
 
103
	@Autowired
104
	private AddressRepository addressRepository;
105
 
106
	@Autowired
107
	private FofoLineItemRepository fofoLineItemRepository;
108
 
109
	@Autowired
110
	private FofoOrderItemRepository fofoOrderItemRepository;
111
 
112
	@Autowired
113
	private PaymentOptionRepository paymentOptionRepository;
114
 
115
	@Autowired
116
	private ScanRecordRepository scanRecordRepository;
117
 
118
	@Autowired
119
	private FofoOrderRepository fofoOrderRepository;
120
 
121
	@Autowired
122
	private RetailerRepository retailerRepository;
123
 
124
	@Autowired
125
	private UserRepository userRepository;
126
 
127
	@Autowired
128
	private UserAccountRepository userAccountRepository;
129
 
130
	@Autowired
131
	private RetailerRegisteredAddressRepository retailerRegisteredAddressRepository;
132
 
133
	@Autowired
134
	private CustomerAddressRepository customerAddressRepository;
135
 
136
	@Autowired
137
	private ItemRepository itemRepository;
138
 
139
	@Autowired
140
	private InsuranceProviderRepository insuranceProviderRepository;
141
 
142
	@Autowired
143
	private InsurancePolicyRepository insurancePolicyRepository;
144
 
145
	@Autowired
146
	private PolicyNumberGenerationSequenceRepository policyNumberGenerationSequenceRepository;
147
 
148
	@Autowired
149
	private PricingService pricingService;
150
 
151
	@Autowired
152
	private PrivateDealUserRepository privateDealUserRepository;
153
 
154
	@Autowired
155
	private CounterRepository counterRepository;
156
 
157
	@Autowired
158
	private SchemeService schemeService;
159
 
160
	@Override
161
	public int createOrder(CreateOrderRequest createOrderRequest, int fofoId) throws ProfitMandiBusinessException {
162
 
22872 ashik.ali 163
		CustomCustomer customCustomer = createOrderRequest.getCustomer();
164
 
165
		if(!StringUtils.isValidEmailAddress(customCustomer.getEmailId())){
166
			LOGGER.error("invalid customer emailId {} ", customCustomer.getEmailId());
22925 ashik.ali 167
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EMAIL_ID, customCustomer.getEmailId(), "VE_1016");
22872 ashik.ali 168
		}
169
 
170
		if(!StringUtils.isValidMobile(customCustomer.getMobileNumber())){
171
			LOGGER.error("invalid customer mobileNumber {} ", customCustomer.getMobileNumber());
22925 ashik.ali 172
			throw new ProfitMandiBusinessException(ProfitMandiConstants.MOBILE_NUMBER, customCustomer.getMobileNumber(), "VE_1071");
22872 ashik.ali 173
		}
174
 
22859 ashik.ali 175
		Map<Integer, Integer> itemIdQuantity = new HashMap<>(); //this is for error
22872 ashik.ali 176
		Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap = new HashMap<>();
22859 ashik.ali 177
		Map<Integer, Float> lineItemPrice = new HashMap<>(); //this is for pricing error
178
 
179
		float totalAmount = 0;
180
		for(CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()){
22872 ashik.ali 181
			//itemIds.add(customFofoOrderItem.getItemId());
22859 ashik.ali 182
			if(!customFofoOrderItem.getSerialNumberDetails().isEmpty() && customFofoOrderItem.getQuantity() != customFofoOrderItem.getSerialNumberDetails().size()){
183
				itemIdQuantity.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
184
			}
185
			if(!(customFofoOrderItem.getSellingPrice() > 0)){
186
				lineItemPrice.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getSellingPrice());
187
			}else{
22863 ashik.ali 188
				totalAmount = totalAmount + customFofoOrderItem.getSellingPrice() * customFofoOrderItem.getQuantity();
189
				totalAmount = totalAmount - customFofoOrderItem.getDiscountAmount() * customFofoOrderItem.getQuantity();
22859 ashik.ali 190
				for(SerialNumberDetail serialNumberDetail : customFofoOrderItem.getSerialNumberDetails()){
191
					if(serialNumberDetail.isInsurance() && serialNumberDetail.getAmount() > 0){
192
						totalAmount = totalAmount + serialNumberDetail.getAmount();
193
					}
194
				}
195
			}
196
 
22872 ashik.ali 197
			itemIdCustomFofoOrderItemMap.put(customFofoOrderItem.getItemId(), customFofoOrderItem);
22859 ashik.ali 198
		}
199
		if(!itemIdQuantity.isEmpty()){
200
			// if item quantity does not match with given serialnumbers size
201
			LOGGER.error("itemId's quantity should be equal to given serialnumber size {} ", itemIdQuantity);
22925 ashik.ali 202
			throw new ProfitMandiBusinessException("itemIdQuantity", itemIdQuantity, "FFORDR_1001");
22859 ashik.ali 203
			//return "error";
204
		}
205
 
206
		this.validatePaymentOptionsAndTotalAmount(createOrderRequest.getPaymentOptions(), totalAmount);
207
 
208
		if(!lineItemPrice.isEmpty()){
209
			// given fofo line item price must be greater than zero
210
			LOGGER.error("requested itemId's selling price must greater than 0");
22925 ashik.ali 211
			throw new ProfitMandiBusinessException(ProfitMandiConstants.PRICE, lineItemPrice, "FFORDR_1002");
22859 ashik.ali 212
		}
213
 
22872 ashik.ali 214
		List<CurrentInventorySnapshot> currentInventorySnapshots = currentInventorySnapshotRepository.selectByFofoItemIds(fofoId, itemIdCustomFofoOrderItemMap.keySet());
22859 ashik.ali 215
 
22872 ashik.ali 216
		this.validateCurrentInventorySnapshotQuantities(currentInventorySnapshots, itemIdCustomFofoOrderItemMap);
22859 ashik.ali 217
 
218
 
22872 ashik.ali 219
		List<Item> items = itemRepository.selectByIds(itemIdCustomFofoOrderItemMap.keySet());
220
		if(items.size() != itemIdCustomFofoOrderItemMap.keySet().size()){
221
			LOGGER.error("Requested ItemIds not found in catalog");
222
			// invalid itemIds 
22925 ashik.ali 223
			throw new ProfitMandiBusinessException("invalidItemIds", itemIdCustomFofoOrderItemMap.keySet(), "FFORDR_1003");
22872 ashik.ali 224
		}
225
 
22859 ashik.ali 226
		Map<Integer, Item>  itemMap = this.toItemMap(items);
227
 
228
		Set<Integer> nonSerializedItemIds = new HashSet<>();
229
		Set<String> serialNumbers = new HashSet<>();
230
		Map<String, Float> insuranceSerialNumberItemPrice = new HashMap<>();
231
		Map<String, Float> insuranceSerialNumberSaleAmount = new HashMap<>();
232
		Map<String, String> serialNumberModelName = new HashMap<>();
233
		Map<String, String> serialNumberBrand = new HashMap<>();
22872 ashik.ali 234
		for (CustomFofoOrderItem customFofoOrderItem: createOrderRequest.getFofoOrderItems()){
235
			Item item = itemMap.get(customFofoOrderItem.getItemId());
22859 ashik.ali 236
			if (item.getType().equals(ItemType.SERIALIZED)){
22872 ashik.ali 237
				for (SerialNumberDetail serialNumberDetail : customFofoOrderItem.getSerialNumberDetails()){
22859 ashik.ali 238
					serialNumbers.add(serialNumberDetail.getSerialNumber());
239
					if(serialNumberDetail.isInsurance()){
22872 ashik.ali 240
						insuranceSerialNumberItemPrice.put(serialNumberDetail.getSerialNumber(), customFofoOrderItem.getSellingPrice());
22859 ashik.ali 241
						insuranceSerialNumberSaleAmount.put(serialNumberDetail.getSerialNumber(), serialNumberDetail.getAmount());
242
						serialNumberModelName.put(serialNumberDetail.getSerialNumber(), item.getModelName());
243
						serialNumberBrand.put(serialNumberDetail.getSerialNumber(), item.getBrand());
244
					}
245
				}
246
			}
247
			else{
22872 ashik.ali 248
				nonSerializedItemIds.add(customFofoOrderItem.getItemId());
22859 ashik.ali 249
			}
250
		}
251
 
252
		Map<Integer, Set<InventoryItem>> serializedInventoryItemMap = new HashMap<>();
253
		Map<Integer, Set<InventoryItem>> nonSerializedInventoryItemMap = new HashMap<>();
254
		Map<Integer, List<Float>> itemIdPriceDropAmount = new HashMap<>();
255
		//Map<String, Float> serialNumberItemPrice = new HashMap<>();
256
 
257
		if (!serialNumbers.isEmpty()){
258
			List<InventoryItem> serializedInventoryItems = inventoryItemRepository.selectByFofoIdSerialNumbers(fofoId, serialNumbers);
259
			LOGGER.info("serializedInventoryItems {}", serializedInventoryItems);
260
			for (InventoryItem inventoryItem : serializedInventoryItems){
261
				if (inventoryItem.getGoodQuantity() == 1){
262
					if (serializedInventoryItemMap.containsKey(inventoryItem.getItemId())){
263
						serializedInventoryItemMap.get(inventoryItem.getItemId()).add(inventoryItem);
264
						itemIdPriceDropAmount.get(inventoryItem.getItemId()).
265
						add(inventoryItem.getUnitPrice() - (inventoryItem.getPriceDropAmount() == null ? 0 : inventoryItem.getPriceDropAmount()));
266
					}
267
					else{
268
						Set<InventoryItem> itemIdInventoryItems = new HashSet<>();
269
						itemIdInventoryItems.add(inventoryItem);
270
						serializedInventoryItemMap.put(inventoryItem.getItemId(), itemIdInventoryItems);
271
						ArrayList<Float> priceDropAmouts = new ArrayList<>();
272
						priceDropAmouts.add(inventoryItem.getUnitPrice() - (inventoryItem.getPriceDropAmount() == null ? 0 : inventoryItem.getPriceDropAmount()));
273
						itemIdPriceDropAmount.put(inventoryItem.getItemId(), priceDropAmouts);
274
					}
275
				}
276
			}
277
		}
278
 
279
		if (!nonSerializedItemIds.isEmpty()){
280
			List<InventoryItem> nonSerializedInventoryItems = inventoryItemRepository.selectByFofoIdItemIds(fofoId, nonSerializedItemIds);
22872 ashik.ali 281
			LOGGER.info("nonSerializedInventoryItems {}", nonSerializedInventoryItems);
22859 ashik.ali 282
			for (InventoryItem it : nonSerializedInventoryItems){
283
				if (it.getGoodQuantity() > 0){
284
					if (nonSerializedInventoryItemMap.containsKey(it.getItemId())){
285
						nonSerializedInventoryItemMap.get(it.getItemId()).add(it);
286
					}
287
					else{
288
						Set<InventoryItem> tmp = new HashSet<>();
289
						tmp.add(it);
290
						nonSerializedInventoryItemMap.put(it.getItemId(), tmp);
291
					}
292
				}
293
			}
294
		}
295
 
22872 ashik.ali 296
		this.validateItemsSerializedNonSerialized(items, itemIdCustomFofoOrderItemMap);
22859 ashik.ali 297
 
298
		Map<Integer, Set<InventoryItem>> inventoryItemsToBill = new HashMap<>();
299
		Map<Integer, Integer> inventoryItemIdQuantityUsed = new HashMap<>(); //to keep track of inventoryitem quanity used for scan records insertion
300
 
301
		LOGGER.info("itemMap keys {}", itemMap.keySet());
302
		//Lets reduce quantity and decide what inventory items to use.
303
		for (Item item : items){
304
			if (item.getType().equals(ItemType.SERIALIZED)){
305
				//TODO:handle null
22872 ashik.ali 306
				if (serializedInventoryItemMap.get(item.getId()) == null || itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().size() != serializedInventoryItemMap.get(item.getId()).size()){
22859 ashik.ali 307
					//not enough serial numbers
308
					//LOGGER.info("serialNumbers {}", serialNumbers);
22872 ashik.ali 309
					//LOGGER.info("serializedInventoryItemMap {}", serializedInventoryItemMap);
310
					LOGGER.error("itemId {} => mismatch size of requested serial numbers", item.getId());
22925 ashik.ali 311
					throw new ProfitMandiBusinessException("invalidSerialNumbers", itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails(), "FFORDR_1004");
22872 ashik.ali 312
				}
22859 ashik.ali 313
				Set<InventoryItem> inventoryItemsSerializedserialized = serializedInventoryItemMap.get(item.getId());
22872 ashik.ali 314
				for (InventoryItem inventoryItem : inventoryItemsSerializedserialized){
315
					inventoryItem.setGoodQuantity(0);
316
					inventoryItemIdQuantityUsed.put(inventoryItem.getId(), 1);
22859 ashik.ali 317
				}
318
				inventoryItemsToBill.put(item.getId(), inventoryItemsSerializedserialized);
319
			}
320
			else{
321
				Set<InventoryItem> inventoryItemsNonSerialized = nonSerializedInventoryItemMap.get(item.getId());
22872 ashik.ali 322
				int quantityToBill = itemIdCustomFofoOrderItemMap.get(item.getId()).getQuantity();
22859 ashik.ali 323
				int totalLeft = quantityToBill;
324
				Set<InventoryItem> inventoryItemsNonSerializedUsed = new HashSet<>();
325
				if (inventoryItemsNonSerialized!=null){
326
					for (InventoryItem inventoryItem : inventoryItemsNonSerialized){
327
						if (totalLeft > 0){
328
							int toUse = Math.min(totalLeft, inventoryItem.getGoodQuantity());
329
							inventoryItemIdQuantityUsed.put(inventoryItem.getId(), toUse);
330
							inventoryItem.setGoodQuantity(inventoryItem.getGoodQuantity()  - toUse);
331
							totalLeft = totalLeft - toUse;
332
							inventoryItemsNonSerializedUsed.add(inventoryItem);
333
						}
334
					}
335
				}
336
 
337
				if (totalLeft > 0){
338
					//not enough quanity for non-serialized
339
					LOGGER.error("not enough quanity for non-serialized");
22925 ashik.ali 340
					throw new ProfitMandiBusinessException("notEnoughQuantityForNonSerialized", totalLeft, "FFORDR_1005");
22859 ashik.ali 341
				}
342
				inventoryItemsToBill.put(item.getId(), inventoryItemsNonSerializedUsed);
343
			}
344
		}
345
 
22872 ashik.ali 346
		Map<Integer, PriceModel> itemIdMopPriceMap = pricingService.getPurchasePriceMopPriceNotFound(itemIdCustomFofoOrderItemMap.keySet(), fofoId);
22859 ashik.ali 347
 
22872 ashik.ali 348
		this.validateMopPrice(itemIdMopPriceMap, itemIdCustomFofoOrderItemMap);
22859 ashik.ali 349
 
350
		InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = this.createAndGetInvoiceNumberGenerationSequence(fofoId);
351
 
352
		Customer customer = this.createAndGetCustomer(customCustomer);
353
 
354
		CustomerAddress customerAddress = null;
355
		if(createOrderRequest.getCustomer().getCustomerAddressId() > 0){
356
			LOGGER.info("CustomerAddressId found [{}]", createOrderRequest.getCustomer().getCustomerAddressId());
357
			try{
358
				customerAddress = customerAddressRepository.selectById(createOrderRequest.getCustomer().getCustomerAddressId());
359
			}catch(ProfitMandiBusinessException profitMandiBusinessException){
360
				LOGGER.warn("Customer address not found with requested customerAddressId [{}]", createOrderRequest.getCustomer().getCustomerAddressId());
361
				customerAddress = this.createCustomerAddress(customCustomer.getAddress());
362
			}
363
		}else{
364
			LOGGER.info("CustomerAddressId not found");
365
			customerAddress = this.createCustomerAddress(customCustomer.getAddress());
366
		}
367
 
368
		customerAddress.setCustomerId(customer.getId());
369
		customerAddressRepository.persist(customerAddress);
370
 
371
		FofoOrder fofoOrder = this.createAndGetFofoOrder(customer.getId(), fofoId, invoiceNumberGenerationSequence, totalAmount, customerAddress.getId());
372
 
373
		this.createPaymentOptions(fofoOrder.getId(), createOrderRequest.getPaymentOptions());
374
 
375
		for(CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()){
376
			FofoOrderItem fofoOrderItem = this.createAndGetFofoOrderItem(customFofoOrderItem, fofoOrder.getId(), itemMap, inventoryItemsToBill.get(customFofoOrderItem.getItemId()), itemIdPriceDropAmount);
377
 
378
			Set<InventoryItem> inventoryItems = inventoryItemsToBill.get(customFofoOrderItem.getItemId());
379
 
380
			this.createFofoLineItem(fofoOrderItem.getId(), inventoryItems, inventoryItemIdQuantityUsed);
381
 
382
			this.updateCurrentInventorySnapshot(currentInventorySnapshots, fofoId, customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
383
 
384
			this.updateInventoryItemsAndScanRecord(inventoryItems, fofoId, inventoryItemIdQuantityUsed);
385
		}
386
 
387
		// insurance calculation is insurance flag is enabled
388
		if(!insuranceSerialNumberItemPrice.isEmpty()){
389
			LOGGER.info("Processing for insurence for serialNumbers");
390
			Map<Float, GadgetCopsInsuranceCalc> insurancePricesMap = pricingService.getInsurancePrices(new HashSet<>(insuranceSerialNumberItemPrice.values()), ProfitMandiConstants.GADGET_COPS);
391
			InsuranceProvider insuranceProvider = insuranceProviderRepository.selectByName(ProfitMandiConstants.GADGET_COPS);
392
 
393
			this.validateInsuranceAmount(insuranceSerialNumberItemPrice, insuranceSerialNumberSaleAmount, insurancePricesMap);
394
 
22872 ashik.ali 395
			this.validateInsuranceMargin(insuranceSerialNumberItemPrice, itemIdCustomFofoOrderItemMap, itemIdMopPriceMap, insurancePricesMap, insuranceSerialNumberSaleAmount);
22859 ashik.ali 396
 
397
			LocalDate customerDateOfBirth = this.validateCustomerDateOfBirth(createOrderRequest.getCustomerDateOfBirth());
398
 
399
			for(Map.Entry<String, Float> entry : insuranceSerialNumberItemPrice.entrySet()){
400
				PolicyNumberGenerationSequence policyNumberGenerationSequence = this.createPolicyNumberGenerationSequence();
401
 
402
				InsurancePolicy insurancePolicy = this.createInsurancePolicy(
403
						invoiceNumberGenerationSequence, fofoId,
404
						insurancePricesMap.get(entry.getValue()).getDealerPrice(),
405
						insuranceSerialNumberSaleAmount.get(entry.getKey()),entry.getValue(),
406
						entry.getKey(), serialNumberModelName.get(entry.getKey()),
407
						serialNumberBrand.get(entry.getKey()), policyNumberGenerationSequence.getSequence(),
408
						insuranceProvider.getId(), customer, customerDateOfBirth, customerAddress);
409
 
410
				GadgetCopsInsuranceModel gadgetCopsInsuranceModel = this.createGadgetCopsInsuranceModel(serialNumberBrand.get(entry.getKey()), serialNumberModelName.get(entry.getKey()), entry.getKey(), customerDateOfBirth, customer, customerAddress, insurancePolicy);
411
 
412
				try{
413
					InsuranceUtils.submitToGadgetCops(gadgetCopsInsuranceModel);
414
					insurancePolicy.setPosted(true);
415
				}catch (ProfitMandiBusinessException profitMandiBusinessException) {
416
					LOGGER.info("Unable to submit insurance policy details to {}", insuranceProvider.getName(), profitMandiBusinessException);
417
				}
418
				insurancePolicyRepository.persist(insurancePolicy);
419
			}
420
		}
421
		float cashback = schemeService.processSchemeOut(fofoOrder.getId(), fofoId);
422
		if(cashback > 0){
423
			fofoOrder.setCashback(cashback);
424
			fofoOrderRepository.persist(fofoOrder);
425
		}
426
		return fofoOrder.getId();
427
	}
428
 
429
	@Override
430
	public PdfModel getInvoicePdfModel(int fofoId, int orderId) throws ProfitMandiBusinessException {
431
 
432
		FofoOrder fofoOrder = fofoOrderRepository.selectByFofoIdAndOrderId(fofoId, orderId);
433
 
434
		PdfModel pdfModel = new PdfModel();
435
		pdfModel.setAuther("profitmandi");
436
		pdfModel.setTitle("Retailer Invoice");
437
		pdfModel.setInvoiceDate(fofoOrder.getFormattedDate());
438
 
439
		// insurance calculation
22925 ashik.ali 440
		List<InsurancePolicy> insurancePolicies = insurancePolicyRepository.selectByRetailerIdInvoiceNumber(fofoId, fofoOrder.getInvoiceNumber());
22859 ashik.ali 441
		Set<CustomInsurancePolicy> customInsurancePolicies = new HashSet<>();
442
		final float totalInsuranceTaxRate = 18;
443
		for(InsurancePolicy insurancePolicy : insurancePolicies){
444
			float taxableInsurancePrice = insurancePolicy.getSaleAmount() / (1 + totalInsuranceTaxRate / 100);
445
			CustomInsurancePolicy customInsurancePolicy = new CustomInsurancePolicy();
446
			customInsurancePolicy.setDescription("Damage Protection Plan for device IMEI #" + insurancePolicy.getSerialNumber() + "\n Certificate No. " + insurancePolicy.getPolicyNumber());
447
			customInsurancePolicy.setHsnCode("998716");
448
			customInsurancePolicy.setRate(taxableInsurancePrice);
449
			customInsurancePolicy.setIgstRate(18);
450
			customInsurancePolicy.setIgstAmount(taxableInsurancePrice * 18 /100);
451
			customInsurancePolicy.setCgstRate(18);
452
			customInsurancePolicy.setCgstAmount(taxableInsurancePrice * 9 /100);
453
			customInsurancePolicy.setSgstRate(9);
454
			customInsurancePolicy.setSgstAmount(taxableInsurancePrice * 9 /100);
455
			customInsurancePolicy.setNetAmount(insurancePolicy.getSaleAmount());
456
			customInsurancePolicies.add(customInsurancePolicy);
457
		}
458
		pdfModel.setInsurancePolicies(customInsurancePolicies);
459
		Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
460
		CustomCustomer customCustomer = new CustomCustomer();
461
		customCustomer.setFirstName(customer.getFirstName());
462
		customCustomer.setLastName(customer.getLastName());
463
		customCustomer.setEmailId(customer.getEmailId());
464
		customCustomer.setMobileNumber(customer.getMobileNumber());
465
		CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId()); 
466
		customCustomer.setAddress(this.createCustomAddress(customerAddress));
467
		pdfModel.setCustomer(customCustomer);
468
		pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
469
		pdfModel.setTotalAmount(fofoOrder.getTotalAmount());
470
 
471
		Retailer retailer = retailerRepository.selectById(fofoId);
472
		PrivateDealUser privateDealUser = null;
473
		try{
474
			privateDealUser = privateDealUserRepository.selectById(retailer.getId());
475
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
476
			LOGGER.error("Private Deal User not found : ", profitMandiBusinessException);
477
		}
478
 
479
		User user = userRepository.selectById(userAccountRepository.selectUserIdByRetailerId(retailer.getId()));
480
		CustomRetailer customRetailer = new CustomRetailer();
481
		customRetailer.setBusinessName(retailer.getName());
482
		customRetailer.setMobileNumber(user.getMobileNumber());
483
		customRetailer.setTinNumber(retailer.getNumber());
484
		if(privateDealUser == null){
485
			customRetailer.setGstNumber(null);
486
		}else{
487
			if(null != privateDealUser.getCounterId()){
488
				Counter counter = counterRepository.selectById(privateDealUser.getCounterId());
489
				customRetailer.setGstNumber(counter.getGstin());
490
			}else{
491
				customRetailer.setGstNumber(null);
492
			}
493
		}
494
		Address retailerAddress = addressRepository.selectById(retailerRegisteredAddressRepository.selectAddressIdByRetailerId(retailer.getId()));
495
		customRetailer.setAddress(this.createCustomAddress(retailerAddress));
496
		pdfModel.setRetailer(customRetailer);
22925 ashik.ali 497
		List<FofoOrderItem> fofoOrderItems = this.getByOrderId(fofoOrder.getId());
22859 ashik.ali 498
 
499
		Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();
500
		for(FofoOrderItem fofoOrderItem : fofoOrderItems){
501
			CustomOrderItem customFofoOrderItem = new CustomOrderItem();
502
			float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
503
			float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
504
			float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
505
 
506
			customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));
507
			customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor() + "\n IMEIS - " + String.join(", ",this.toSerialNumbers(fofoOrderItem.getFofoLineItems())));
508
			customFofoOrderItem.setRate(taxableSellingPrice);
509
			customFofoOrderItem.setDiscount(taxableDiscountPrice);
510
			customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());
511
			customFofoOrderItem.setNetAmount((fofoOrderItem.getSellingPrice()-fofoOrderItem.getDiscount())*fofoOrderItem.getQuantity());
512
			float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
513
			float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
514
			float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
515
			customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
516
			customFofoOrderItem.setIgstAmount(igstAmount);
517
			customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
518
			customFofoOrderItem.setCgstAmount(cgstAmount);
519
			customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
520
			customFofoOrderItem.setSgstAmount(sgstAmount);
521
			customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
522
			customerFofoOrderItems.add(customFofoOrderItem);
523
		}
524
		pdfModel.setOrderItems(customerFofoOrderItems);
525
		return pdfModel;
526
	}
527
 
528
	public String getBillingAddress(CustomerAddress customerAddress) {
529
		StringBuilder address = new StringBuilder();
530
		if ((customerAddress.getLine1() != null) && (!customerAddress.getLine1().isEmpty())) {
531
			address.append(customerAddress.getLine1());
532
			address.append(", ");
533
		}
534
 
535
		if ((customerAddress.getLine2() != null) && (!customerAddress.getLine2().isEmpty())) {
536
			address.append(customerAddress.getLine2());
537
			address.append(", ");
538
		}
539
 
540
		if ((customerAddress.getLandmark() != null) && (!customerAddress.getLandmark().isEmpty())) {
541
			address.append(customerAddress.getLandmark());
542
			address.append(", ");
543
		}
544
 
545
		if ((customerAddress.getCity() != null) && (!customerAddress.getCity().isEmpty())) {
546
			address.append(customerAddress.getCity());
547
			address.append(", ");
548
		}
549
 
550
		if ((customerAddress.getState() != null) && (!customerAddress.getState().isEmpty())) {
551
			address.append(customerAddress.getState());
552
		}
553
 
554
		if ((customerAddress.getPinCode() != null) && (!customerAddress.getPinCode().isEmpty())) {
555
			address.append("- ");
556
			address.append(customerAddress.getPinCode());
557
		}
558
 
559
		return address.toString();
560
	}
561
 
562
	@Override
563
	public List<CartFofo> cartCheckout(String cartJson) throws ProfitMandiBusinessException{
564
		try{
565
			JSONObject cartObject = new JSONObject(cartJson);
566
			Iterator<?> keys = cartObject.keys();
567
 
568
			Set<Integer> itemIds = new HashSet<>();
569
			List<CartFofo> cartItems = new ArrayList<CartFofo>();
570
 
571
			while( keys.hasNext() ) {
572
				String key = (String)keys.next();
573
				if ( cartObject.get(key) instanceof JSONObject ) {
574
					LOGGER.info(cartObject.get(key).toString());
575
				}
576
				CartFofo cf = new CartFofo();
577
				cf.setItemId(cartObject.getJSONObject(key).getInt("itemId"));
578
				cf.setQuantity(cartObject.getJSONObject(key).getInt("quantity"));
579
 
580
				if (cf.getQuantity() <= 0){
581
					continue;
582
				}
583
				cartItems.add(cf);
584
				itemIds.add(cartObject.getJSONObject(key).getInt("itemId"));
585
			}
586
			Map<Integer, Item>  itemMap = new HashMap<Integer, Item>();
587
			if (itemIds.size() > 0){
588
				List<Item> items = itemRepository.selectByIds(itemIds);
589
				for (Item i : items){
590
					itemMap.put(i.getId(), i);
591
				}
592
 
593
			}
594
			for (CartFofo cf : cartItems){
595
				Item i = itemMap.get(cf.getItemId());
596
				if (i == null){
597
					continue;
598
				}
599
				cf.setDisplayName(getValidName(i.getBrand())+" "+getValidName(i.getModelName())+" "+getValidName(i.getModelNumber())+" "+getValidName(i.getColor()).replaceAll("\\s+", " "));
600
				cf.setItemType(i.getType());
601
			}
602
			return cartItems;
603
		}catch (Exception e) {
604
			LOGGER.error("Unable to Prepare cart to place order...", e);
22925 ashik.ali 605
			throw new ProfitMandiBusinessException("cartData", cartJson, "FFORDR_1006");
22859 ashik.ali 606
		}
607
	}
608
 
609
	private String getValidName(String name){
610
		return name!=null?name:"";
611
	}
612
 
613
	private Set<String> toSerialNumbers(Set<FofoLineItem> fofoLineItems){
614
		Set<String> serialNumbers = new HashSet<>();
615
		for(FofoLineItem fofoLineItem : fofoLineItems){
616
			serialNumbers.add(fofoLineItem.getSerialNumber());
617
		}
618
		return serialNumbers;	
619
	}
620
 
621
 
622
	private PolicyNumberGenerationSequence createPolicyNumberGenerationSequence(){
623
		PolicyNumberGenerationSequence policyNumberGenerationSequence = null;
624
		try{
625
			policyNumberGenerationSequence = policyNumberGenerationSequenceRepository.select();
626
			policyNumberGenerationSequence.setSequence(policyNumberGenerationSequence.getSequence() + 1);
627
			policyNumberGenerationSequenceRepository.persist(policyNumberGenerationSequence);
628
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
629
			policyNumberGenerationSequence = new PolicyNumberGenerationSequence();
630
			policyNumberGenerationSequence.setSequence(1);
631
			policyNumberGenerationSequenceRepository.persist(policyNumberGenerationSequence);
632
		}
633
		return policyNumberGenerationSequence;
634
	}
635
 
636
	private GadgetCopsInsuranceModel createGadgetCopsInsuranceModel(String brand, String modelName, String serialNumber, LocalDate customerDateOfBirth, Customer customer, CustomerAddress customerAddress, InsurancePolicy insurancePolicy){
637
		GadgetCopsInsuranceModel gadgetCopsInsuranceModel = new GadgetCopsInsuranceModel();
638
		gadgetCopsInsuranceModel.setBrand(brand);
639
		gadgetCopsInsuranceModel.setModelName(modelName);
640
		gadgetCopsInsuranceModel.setSerialNumber(serialNumber);
641
		gadgetCopsInsuranceModel.setCustomerFirstName(customer.getFirstName());
642
		gadgetCopsInsuranceModel.setCustomerLastName(customer.getLastName());
643
		gadgetCopsInsuranceModel.setCustomerDateOfBirth(customerDateOfBirth);
644
		gadgetCopsInsuranceModel.setCustomerMobileNumber(customer.getMobileNumber());
645
		gadgetCopsInsuranceModel.setCustomerEmailId(customer.getEmailId());
646
		gadgetCopsInsuranceModel.setCustomerAddress1(customerAddress.getLine1());
647
		gadgetCopsInsuranceModel.setCustomerAddress2(customerAddress.getLine2());
648
		gadgetCopsInsuranceModel.setCustomerCity(customerAddress.getCity());
649
		gadgetCopsInsuranceModel.setCustomerPinCode(customerAddress.getPinCode());
650
		gadgetCopsInsuranceModel.setCustomerState(customerAddress.getState());
651
		gadgetCopsInsuranceModel.setPrice(insurancePolicy.getSellingPrice());
652
		gadgetCopsInsuranceModel.setInvoiceNumber(insurancePolicy.getInvoiceNumber());
653
		gadgetCopsInsuranceModel.setPolicyNumber(insurancePolicy.getPolicyNumber());
654
		return gadgetCopsInsuranceModel;
655
	}
656
 
657
	private InsurancePolicy createInsurancePolicy(InvoiceNumberGenerationSequence invoiceNumberGenerationSequence, int retailerId, float purchaseAmount, float saleAmount, float sellingPrice, String serialNumber, String modelName, String brand, int policyNumberGenerationSequence, int insuranceProviderId, Customer customer, LocalDate customerDateOfBirth, CustomerAddress customerAddress){
658
		InsurancePolicy insurancePolicy = new InsurancePolicy();
659
		insurancePolicy.setInvoiceNumber(invoiceNumberGenerationSequence.getPrefix() + invoiceNumberGenerationSequence.getSequence());
660
		insurancePolicy.setRetailerId(retailerId);
661
		insurancePolicy.setPurchaseAmount(purchaseAmount);
662
		insurancePolicy.setSaleAmount(saleAmount);
663
		insurancePolicy.setSellingPrice(sellingPrice);
664
		insurancePolicy.setSerialNumber(serialNumber);
665
		insurancePolicy.setModelName(modelName);
666
		insurancePolicy.setBrand(brand);
667
		insurancePolicy.setPolicyNumber(StringUtils.generatePolicyNumber(ProfitMandiConstants.POLICY_NUMBER_PREFIX, policyNumberGenerationSequence));
668
		insurancePolicy.setProviderId(insuranceProviderId);
669
		insurancePolicy.setCustomerFirstName(customer.getFirstName());
670
		insurancePolicy.setCustomerLastName(customer.getLastName());
671
		insurancePolicy.setCustomerMobileNumber(customer.getMobileNumber());
672
		insurancePolicy.setCustomerEmailId(customer.getEmailId());
673
		insurancePolicy.setCustomerDateOfBirth(customerDateOfBirth);
674
		insurancePolicy.setCustomerAddress1(customerAddress.getLine1());
675
		insurancePolicy.setCustomerAddress2(customerAddress.getLine2());
676
		insurancePolicy.setCustomerCity(customerAddress.getCity());
677
		insurancePolicy.setCustomerPinCode(customerAddress.getPinCode());
678
		insurancePolicy.setCustomerState(customerAddress.getState());
679
		return insurancePolicy;
680
	}
681
 
22872 ashik.ali 682
	private void validateInsuranceMargin(Map<String, Float> insuranceSerialNumberItemPrice, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap, Map<Integer, PriceModel> itemIdMopPriceMap, Map<Float, GadgetCopsInsuranceCalc> insurancePricesMap, Map<String, Float> insuranceSerialNumberSaleAmount) throws ProfitMandiBusinessException{
22859 ashik.ali 683
		Map<Float, Float> invalidInsuranceMarginAmount = new HashMap<>();
684
		for(Map.Entry<String, Float> entry : insuranceSerialNumberItemPrice.entrySet()){
22872 ashik.ali 685
			int itemId = this.getItemIdFromSerialNumber(itemIdCustomFofoOrderItemMap, entry.getKey());
22859 ashik.ali 686
			float itemPurchasePrice = itemIdMopPriceMap.get(itemId).getPrice();
687
			float itemSellingPrice = entry.getValue();
688
			float itemMargin = itemSellingPrice - itemPurchasePrice;
689
			float insurancePurchasePrice = insurancePricesMap.get(entry.getValue()).getDealerPrice();
690
			float insuranceSellingPrice = insuranceSerialNumberSaleAmount.get(entry.getKey());
691
			float insuranceMargin = insuranceSellingPrice - insurancePurchasePrice;
692
			if(insuranceMargin < (itemMargin * 30 / 100)){
693
				invalidInsuranceMarginAmount.put(insuranceMargin, (itemMargin * 30 / 100));
694
			}
695
		}
696
		if(!invalidInsuranceMarginAmount.isEmpty()){
697
			LOGGER.error("insurance marging should be greater than equal to item profit margin insuranceMarginItemIdMargin {}", invalidInsuranceMarginAmount);
22925 ashik.ali 698
			throw new ProfitMandiBusinessException("invalidInsuranceMarginAmount", invalidInsuranceMarginAmount, "FFORDR_1007");
22859 ashik.ali 699
		}
700
	}
701
 
702
	private void validateInsuranceAmount(Map<String, Float> insuranceSerialNumberItemPrice, Map<String, Float> insuranceSerialNumberSaleAmount, Map<Float, GadgetCopsInsuranceCalc> insurancePricesMap) throws ProfitMandiBusinessException{
703
		Map<Float, Float> invalidInsurancePurchaseSaleAmount = new HashMap<>();
704
		Map<Float, Float> invalidInsuranceSalePurchaseAmount = new HashMap<>();
705
		for(Map.Entry<String, Float> entry : insuranceSerialNumberItemPrice.entrySet()){
706
			if(insuranceSerialNumberSaleAmount.get(entry.getKey()) < insurancePricesMap.get(entry.getValue()).getDealerPrice()){
707
				invalidInsurancePurchaseSaleAmount.put(insurancePricesMap.get(entry.getValue()).getDealerPrice(), insuranceSerialNumberSaleAmount.get(entry.getKey()));
708
			}
709
 
710
			if(insuranceSerialNumberSaleAmount.get(entry.getKey()) > insurancePricesMap.get(entry.getValue()).getSellingPrice()){
711
				invalidInsuranceSalePurchaseAmount.put(insuranceSerialNumberSaleAmount.get(entry.getKey()), insurancePricesMap.get(entry.getValue()).getDealerPrice());
712
			}
713
		}
714
 
715
		// insurance sale amount can not be lesser than insurance purchase amount
716
		if(!invalidInsurancePurchaseSaleAmount.isEmpty()){
717
			LOGGER.error("Invalid Insurance prices [{}], insurance sale amount can not be lesser than insurance purchase amount", invalidInsurancePurchaseSaleAmount);
22925 ashik.ali 718
			throw new ProfitMandiBusinessException("invalidInsurancePurchaseSaleAmount", invalidInsurancePurchaseSaleAmount, "FFORDR_1008");
22859 ashik.ali 719
		}
720
 
721
		if(!invalidInsuranceSalePurchaseAmount.isEmpty()){
722
			LOGGER.error("Invalid Insurance prices [{}], insurance sale amount can not be greater than than insurance max amount", invalidInsuranceSalePurchaseAmount);
22925 ashik.ali 723
			throw new ProfitMandiBusinessException("invalidInsuranceSalePurchaseAmount", invalidInsuranceSalePurchaseAmount, "FFORDR_1009");
22859 ashik.ali 724
		}
725
	}
726
 
22872 ashik.ali 727
	private void validateMopPrice(Map<Integer, PriceModel> itemIdMopPriceMap, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException{
22859 ashik.ali 728
		Map<Integer, Float> invalidMopItemIdPriceMap = new HashMap<>();
729
		Map<Integer, Float> invalidDiscountAmountMap = new HashMap<>();
730
		//Map<Integer, PriceModel> itemIdMopPriceMap = pricingService.getPurchasePriceMopPriceNotFound(itemIds, fofoId);
731
		for(Map.Entry<Integer, PriceModel> entry : itemIdMopPriceMap.entrySet()){
22872 ashik.ali 732
			CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoLineItemMap.get(entry.getKey());
733
			if(entry.getValue().getPrice() < Float.MAX_VALUE && customFofoOrderItem.getSellingPrice() < entry.getValue().getPrice()){
734
				invalidMopItemIdPriceMap.put(entry.getKey(), customFofoOrderItem.getSellingPrice());
22859 ashik.ali 735
			}
22872 ashik.ali 736
			if(entry.getValue().isMop() && customFofoOrderItem.getDiscountAmount() > entry.getValue().getMaxDiscountAmount()){
737
				invalidDiscountAmountMap.put(entry.getKey(), customFofoOrderItem.getDiscountAmount());
738
			}
22859 ashik.ali 739
		}
740
 
741
		if(!invalidMopItemIdPriceMap.isEmpty()){
742
			LOGGER.error("Invalid itemIds selling prices{} should be greater than mop prices {}", invalidMopItemIdPriceMap, itemIdMopPriceMap);
22925 ashik.ali 743
			throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidMopItemIdPriceMap, "FFORDR_1010");
22859 ashik.ali 744
		}
745
 
746
		if(!invalidMopItemIdPriceMap.isEmpty()){
747
			LOGGER.error("Invalid itemIds discount amounts {} should be less than maxDiscount prices {}", invalidDiscountAmountMap, itemIdMopPriceMap);
22925 ashik.ali 748
			throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidDiscountAmountMap, "FFORDR_1011");
22859 ashik.ali 749
		}
750
	}
751
 
752
	private LocalDate validateCustomerDateOfBirth(String customerDateOfBirthString) throws ProfitMandiBusinessException{
753
		LocalDate customerDateOfBirth = null;
754
		try{
755
			customerDateOfBirth = StringUtils.toDate(customerDateOfBirthString);
756
		}catch(DateTimeException dateTimeException){
757
			LOGGER.error("Unable to parse dateOfBirth", dateTimeException);
22925 ashik.ali 758
			throw new ProfitMandiBusinessException("dateOfBirth", customerDateOfBirthString, "FFORDR_1012");
22859 ashik.ali 759
		}
760
		return customerDateOfBirth;
761
	}
762
 
763
	private void updateInventoryItemsAndScanRecord(Set<InventoryItem> inventoryItems, int fofoId, Map<Integer, Integer> inventoryItemQuantityUsed){
764
		for(InventoryItem inventoryItem : inventoryItems){
765
			inventoryItem.setLastScanType(ScanType.SALE);
766
			inventoryItemRepository.persist(inventoryItem);
767
			ScanRecord scanRecord = new ScanRecord();
768
			scanRecord.setInventoryItemId(inventoryItem.getId());
769
			scanRecord.setFofoId(fofoId);
770
			//correct this
771
			scanRecord.setQuantity(inventoryItemQuantityUsed.get(inventoryItem.getId()));
772
			scanRecord.setType(ScanType.SALE);
773
			scanRecordRepository.persist(scanRecord);
774
		}
775
	}
776
 
777
	private void createFofoLineItem(int fofoOrderItemId, Set<InventoryItem> inventoryItems, Map<Integer, Integer> inventoryItemIdQuantityUsed){
778
		for(InventoryItem inventoryItem : inventoryItems){
779
			FofoLineItem fofoLineItem = new FofoLineItem();
780
			fofoLineItem.setFofoOrderItemId(fofoOrderItemId);
781
			fofoLineItem.setSerialNumber(inventoryItem.getSerialNumber());
782
			fofoLineItem.setInventoryItemId(inventoryItem.getId());
783
			fofoLineItem.setQuantity(inventoryItemIdQuantityUsed.get(inventoryItem.getId()));
784
			fofoLineItemRepository.persist(fofoLineItem);
785
		}
786
	}
787
 
788
	private FofoOrderItem createAndGetFofoOrderItem(CustomFofoOrderItem customFofoOrderItem, int fofoOrderId, Map<Integer, Item> itemMap, Set<InventoryItem> inventoryItems, Map<Integer, List<Float>> itemIdPriceDropAmount){
789
		FofoOrderItem fofoOrderItem = new FofoOrderItem();
790
		fofoOrderItem.setItemId(customFofoOrderItem.getItemId());
791
		fofoOrderItem.setQuantity(customFofoOrderItem.getQuantity());
792
		fofoOrderItem.setSellingPrice(customFofoOrderItem.getSellingPrice());
793
		fofoOrderItem.setOrderId(fofoOrderId);
794
		fofoOrderItem.setDp(customFofoOrderItem.getSellingPrice());
795
		fofoOrderItem.setDiscount(customFofoOrderItem.getDiscountAmount());
796
		Item item = itemMap.get(customFofoOrderItem.getItemId());
797
		for(InventoryItem inventoryItem : inventoryItems){
798
			fofoOrderItem.setIgstRate(inventoryItem.getIgstRate());
799
			fofoOrderItem.setCgstRate(inventoryItem.getCgstRate());
800
			fofoOrderItem.setSgstRate(inventoryItem.getSgstRate());
801
			fofoOrderItem.setHsnCode(inventoryItem.getHsnCode());
802
			break;
803
		}
804
		List<Float> priceDropAmounts = itemIdPriceDropAmount.get(customFofoOrderItem.getItemId());
805
		float cost = 0;
806
		if (priceDropAmounts!=null){
807
			for (Float pda : priceDropAmounts){
808
				cost = cost + pda;
809
			}
810
		}
811
		else{
812
			cost = customFofoOrderItem.getSellingPrice() * customFofoOrderItem.getQuantity();
813
		}
814
		fofoOrderItem.setCost(cost);
815
		fofoOrderItem.setBrand(item.getBrand());
816
		fofoOrderItem.setModelName(item.getModelName());
817
		fofoOrderItem.setModelNumber(item.getModelNumber());
818
		fofoOrderItem.setColor(item.getColor());
819
		fofoOrderItemRepository.persist(fofoOrderItem);
820
		return fofoOrderItem;
821
	}
822
 
823
	private void updateCurrentInventorySnapshot(List<CurrentInventorySnapshot> currentInventorySnapshots, int fofoId, int itemId, int quantity) throws ProfitMandiBusinessException{
824
		for(CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots){
825
			if(currentInventorySnapshot.getItemId() == itemId && currentInventorySnapshot.getFofoId() == fofoId){
826
				currentInventorySnapshotRepository.updateAvailabilityByItemIdAndFofoId(itemId, fofoId, currentInventorySnapshot.getAvailability() - quantity);
827
			}
828
		}
829
	}
830
 
831
	private void createPaymentOptions(int fofoOrderId, Set<CustomPaymentOption> customPaymentOptions){
832
		for(CustomPaymentOption customPaymentOption : customPaymentOptions){
833
			if(customPaymentOption.getAmount() > 0){
834
				PaymentOption paymentOption = new PaymentOption();
835
				paymentOption.setOrderId(fofoOrderId);
836
				paymentOption.setAmount(customPaymentOption.getAmount());
837
				paymentOption.setType(PaymentOptionType.valueOf(customPaymentOption.getType()));
838
				paymentOptionRepository.persist(paymentOption);
839
			}
840
		}
841
	}
842
 
843
	private FofoOrder createAndGetFofoOrder(int customerId, int fofoId, InvoiceNumberGenerationSequence invoiceNumberGenerationSequence, float totalAmount, int customerAddressId){
844
		FofoOrder fofoOrder = new FofoOrder();
845
		fofoOrder.setCustomerId(customerId);
846
		fofoOrder.setFofoId(fofoId);
847
		fofoOrder.setInvoiceNumber(invoiceNumberGenerationSequence.getPrefix() + invoiceNumberGenerationSequence.getSequence());
848
		fofoOrder.setTotalAmount(totalAmount);
849
		fofoOrder.setCustomerAddressId(customerAddressId);
850
		fofoOrderRepository.persist(fofoOrder);
851
		return fofoOrder;
852
	}
853
 
854
	private Customer createAndGetCustomer(CustomCustomer customCustomer) throws ProfitMandiBusinessException{
855
		Customer customer = null;
856
		try{
857
			customer = customerRepository.selectByMobileNumber(customCustomer.getMobileNumber());
858
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
859
			LOGGER.error("Error : ", profitMandiBusinessException);
860
			customer = new Customer();
861
			customer.setFirstName(customCustomer.getFirstName());
862
			customer.setLastName(customCustomer.getLastName());
863
			customer.setEmailId(customCustomer.getEmailId());
864
			customer.setMobileNumber(customCustomer.getMobileNumber());
865
			customerRepository.persist(customer);
866
		}
867
		return customer;
868
	}
869
 
870
	private InvoiceNumberGenerationSequence createAndGetInvoiceNumberGenerationSequence(int fofoId){
871
		InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;
872
		try{
873
			invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);
874
			invoiceNumberGenerationSequence.setSequence(invoiceNumberGenerationSequence.getSequence() + 1);
875
		}catch(ProfitMandiBusinessException profitMandiBusinessException){
876
			invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();
877
			invoiceNumberGenerationSequence.setFofoId(fofoId);
878
			invoiceNumberGenerationSequence.setPrefix("INVOICE");
879
			invoiceNumberGenerationSequence.setSequence(1);
880
		}
881
		invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);
882
		return invoiceNumberGenerationSequence;
883
	}
884
 
22872 ashik.ali 885
	private void validateItemsSerializedNonSerialized(List<Item> items, Map<Integer, CustomFofoOrderItem> customFofoOrderItemMap) throws ProfitMandiBusinessException{
22859 ashik.ali 886
 		List<Integer> invalidItemIdSerialNumbers = new ArrayList<Integer>();
887
		List<Integer> itemIdNonSerializedSerialNumbers = new ArrayList<Integer>();
888
		for (Item i : items){
22872 ashik.ali 889
			CustomFofoOrderItem customFofoOrderItem = customFofoOrderItemMap.get(i.getId());
890
			if (i.getType().equals(ItemType.SERIALIZED)){
891
				if (customFofoOrderItem == null || customFofoOrderItem.getSerialNumberDetails().isEmpty()){
892
					invalidItemIdSerialNumbers.add(i.getId());
22859 ashik.ali 893
				}
22872 ashik.ali 894
			}
895
			else{
896
				if (customFofoOrderItem == null || !customFofoOrderItem.getSerialNumberDetails().isEmpty()){
897
					itemIdNonSerializedSerialNumbers.add(i.getId());
22859 ashik.ali 898
				}
899
			}
900
		}
901
 
902
		if(!invalidItemIdSerialNumbers.isEmpty()){
903
			LOGGER.error("Invalid itemId's serialNumbers for serialized{}", invalidItemIdSerialNumbers);
904
			// itemId's are serialized you are saying these are not serialized
22925 ashik.ali 905
			throw new ProfitMandiBusinessException("invalidItemIdSerialNumbers", invalidItemIdSerialNumbers, "FFORDR_1013");
22859 ashik.ali 906
		}
907
 
908
		if(!itemIdNonSerializedSerialNumbers.isEmpty()){
909
			LOGGER.error("Invalid itemId's serialNumbers for non serialized{}", itemIdNonSerializedSerialNumbers);
910
			// itemId's are non serialized you are saying these are serialized
22925 ashik.ali 911
			throw new ProfitMandiBusinessException("itemIdNonSerializedSerialNumbers", itemIdNonSerializedSerialNumbers, "FFORDR_1014");
22859 ashik.ali 912
		}
913
	}
914
 
22872 ashik.ali 915
	private void validateCurrentInventorySnapshotQuantities(List<CurrentInventorySnapshot> currentInventorySnapshots, Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap) throws ProfitMandiBusinessException{
916
		if(itemIdCustomFofoOrderItemMap.keySet().size() != currentInventorySnapshots.size()){
22859 ashik.ali 917
			throw new ProfitMandiBusinessException("quantiiesSize", currentInventorySnapshots.size(), "");
918
		}
919
		List<ItemIdQuantityAvailability> itemIdQuantityAvailabilities = new ArrayList<>(); //this is for error
920
		LOGGER.info("currentInventorySnapshots "+currentInventorySnapshots);
22872 ashik.ali 921
		LOGGER.info("CustomFofoLineItemMap {}", itemIdCustomFofoOrderItemMap);
22859 ashik.ali 922
		for(CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots){
22872 ashik.ali 923
			CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoOrderItemMap.get(currentInventorySnapshot.getItemId());
924
			LOGGER.info("customFofoOrderItem {}", customFofoOrderItem);
925
			if(customFofoOrderItem.getQuantity() > currentInventorySnapshot.getAvailability()){
22859 ashik.ali 926
					ItemIdQuantityAvailability itemIdQuantityAvailability = new ItemIdQuantityAvailability();
927
					itemIdQuantityAvailability.setItemId(customFofoOrderItem.getItemId());
928
					Quantity quantity = new Quantity();
929
					quantity.setAvailable(currentInventorySnapshot.getAvailability());
930
					quantity.setRequested(customFofoOrderItem.getQuantity());
931
					itemIdQuantityAvailability.setQuantity(quantity);
932
					itemIdQuantityAvailabilities.add(itemIdQuantityAvailability);
933
				}
934
 
935
		}
936
 
937
 
938
 
939
		if(!itemIdQuantityAvailabilities.isEmpty()){
940
			// itemIdQuantity request is not valid
941
			LOGGER.error("Requested quantities should not be greater than currently available quantities {}", itemIdQuantityAvailabilities);
22925 ashik.ali 942
			throw new ProfitMandiBusinessException("itemIdQuantityAvailabilities", itemIdQuantityAvailabilities, "FFORDR_1015");
22859 ashik.ali 943
		}
944
	}
945
 
22872 ashik.ali 946
	private int getItemIdFromSerialNumber(Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap, String serialNumber){
947
		int itemId = 0;
948
		for(Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoOrderItemMap.entrySet()){
949
			Set<SerialNumberDetail> serialNumberDetails = entry.getValue().getSerialNumberDetails();
950
			for(SerialNumberDetail serialNumberDetail : serialNumberDetails){
951
				if(serialNumberDetail.getSerialNumber().equals(serialNumber)){
952
					itemId = entry.getKey();
953
					break;
954
				}
22859 ashik.ali 955
			}
956
		}
22872 ashik.ali 957
		return itemId;
22859 ashik.ali 958
	}
959
 
960
	private Map<Integer, Item> toItemMap(List<Item> items){
961
		Map<Integer, Item>  itemMap = new HashMap<Integer, Item>();
962
		for (Item i : items){
963
			itemMap.put(i.getId(), i);
964
		}
965
		return itemMap;
966
	}
967
 
968
	private CustomerAddress createCustomerAddress(CustomAddress customAddress){
969
		CustomerAddress customerAddress = new CustomerAddress();
970
		customerAddress.setName(customAddress.getName());
971
		customerAddress.setLine1(customAddress.getLine1());
972
		customerAddress.setLine2(customAddress.getLine2());
973
		customerAddress.setLandmark(customAddress.getLandmark());
974
		customerAddress.setCity(customAddress.getCity());
975
		customerAddress.setPinCode(customAddress.getPinCode());
976
		customerAddress.setState(customAddress.getState());
977
		customerAddress.setCountry(customAddress.getCountry());
978
		customerAddress.setPhoneNumber(customAddress.getPhoneNumber());
979
		return customerAddress;
980
	}
981
 
982
	private CustomAddress createCustomAddress(Address address){
983
		CustomAddress customAddress = new CustomAddress();
984
		customAddress.setName(address.getName());
985
		customAddress.setLine1(address.getLine1());
986
		customAddress.setLine2(address.getLine2());
987
		customAddress.setLandmark(address.getLandmark());
988
		customAddress.setCity(address.getCity());
989
		customAddress.setPinCode(address.getPinCode());
990
		customAddress.setState(address.getState());
991
		customAddress.setCountry(address.getCountry());
992
		customAddress.setPhoneNumber(address.getPhoneNumber());
993
		return customAddress;
994
	}
995
 
996
	private CustomAddress createCustomAddress(CustomerAddress customerAddress){
997
		CustomAddress customAddress = new CustomAddress();
998
		customAddress.setName(customerAddress.getName());
999
		customAddress.setLine1(customerAddress.getLine1());
1000
		customAddress.setLine2(customerAddress.getLine2());
1001
		customAddress.setLandmark(customerAddress.getLandmark());
1002
		customAddress.setCity(customerAddress.getCity());
1003
		customAddress.setPinCode(customerAddress.getPinCode());
1004
		customAddress.setState(customerAddress.getState());
1005
		customAddress.setCountry(customerAddress.getCountry());
1006
		customAddress.setPhoneNumber(customerAddress.getPhoneNumber());
1007
		return customAddress;
1008
	}
1009
 
1010
	private void validatePaymentOptionsAndTotalAmount(Set<CustomPaymentOption> customPaymentOptions, float totalAmount) throws ProfitMandiBusinessException
1011
	{
1012
		float calculatedAmount = 0;
1013
		Set<String> paymentOptionTypes = new HashSet<>();
1014
		for(CustomPaymentOption customPaymentOption : customPaymentOptions){
1015
			if(paymentOptionTypes.contains(PaymentOptionType.valueOf(customPaymentOption.getType()))){
1016
				throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_TYPE, customPaymentOption.getType(), "");
1017
			}else{
1018
				paymentOptionTypes.add(customPaymentOption.getType());
1019
				calculatedAmount = calculatedAmount + customPaymentOption.getAmount();
1020
			}
1021
		}
1022
		if(calculatedAmount != totalAmount){
22863 ashik.ali 1023
			LOGGER.warn("Error occured while validating payment options amount[{}] != TotalAmount [{}]", calculatedAmount, totalAmount);
22925 ashik.ali 1024
			throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_CALCULATED_AMOUNT, calculatedAmount, "FFORDR_1016");
22859 ashik.ali 1025
		}
1026
	}
22925 ashik.ali 1027
 
1028
	@Override
1029
	public List<FofoOrderItem> getByOrderId(int orderId) throws ProfitMandiBusinessException {
1030
		List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(orderId);
1031
		if(!fofoOrderItems.isEmpty()){
1032
			List<FofoOrderItem> newFofoOrderItems = new ArrayList<>();
1033
			Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = this.toFofoOrderItemIdFofoLineItems(fofoOrderItems);
1034
			Iterator<FofoOrderItem> fofoOrderItemsIterator = fofoOrderItems.iterator();
1035
			while(fofoOrderItemsIterator.hasNext()){
1036
				FofoOrderItem fofoOrderItem = fofoOrderItemsIterator.next();
1037
				fofoOrderItem.setFofoLineItems(fofoOrderItemIdFofoLineItemsMap.get(fofoOrderItem.getId()));
1038
				newFofoOrderItems.add(fofoOrderItem);
1039
				fofoOrderItemsIterator.remove();
1040
			}
1041
			fofoOrderItems = newFofoOrderItems;
1042
		}
1043
		return fofoOrderItems;
1044
	}
1045
 
1046
	private Set<Integer> toFofoOrderItemIds(List<FofoOrderItem> fofoOrderItems){
1047
		Set<Integer> fofoOrderItemIds = new HashSet<>();
1048
		for(FofoOrderItem fofoOrderItem : fofoOrderItems){
1049
			fofoOrderItemIds.add(fofoOrderItem.getId());
1050
		}
1051
		return fofoOrderItemIds;
1052
	}
1053
 
1054
	private Map<Integer, Set<FofoLineItem>> toFofoOrderItemIdFofoLineItems(List<FofoOrderItem> fofoOrderItems){
1055
		Set<Integer> fofoOrderItemIds = this.toFofoOrderItemIds(fofoOrderItems);
1056
		List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIds);
1057
		Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = new HashMap<>();
1058
		for(FofoLineItem fofoLineItem : fofoLineItems){
1059
			if(!fofoOrderItemIdFofoLineItemsMap.containsKey(fofoLineItem.getFofoOrderItemId())){
1060
				Set<FofoLineItem> fofoLineItems2 = new HashSet<>();
1061
				fofoLineItems2.add(fofoLineItem);
1062
				fofoOrderItemIdFofoLineItemsMap.put(fofoLineItem.getFofoOrderItemId(), fofoLineItems2);
1063
			}else{
1064
				fofoOrderItemIdFofoLineItemsMap.get(fofoLineItem.getFofoOrderItemId()).add(fofoLineItem);
1065
			}
1066
		}
1067
		return fofoOrderItemIdFofoLineItemsMap;
1068
	}
22859 ashik.ali 1069
 
1070
}