Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
22653 ashik.ali 1
package com.spice.profitmandi.service.scheme;
2
 
22859 ashik.ali 3
import java.time.LocalDateTime;
23019 ashik.ali 4
import java.util.ArrayList;
22653 ashik.ali 5
import java.util.HashMap;
22859 ashik.ali 6
import java.util.HashSet;
22653 ashik.ali 7
import java.util.List;
8
import java.util.Map;
9
import java.util.Set;
10
 
22859 ashik.ali 11
import org.slf4j.Logger;
12
import org.slf4j.LoggerFactory;
22653 ashik.ali 13
import org.springframework.beans.factory.annotation.Autowired;
14
import org.springframework.stereotype.Component;
15
 
22859 ashik.ali 16
import com.spice.profitmandi.common.enumuration.DateTimePattern;
22653 ashik.ali 17
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
22859 ashik.ali 18
import com.spice.profitmandi.common.model.CreateSchemeRequest;
22653 ashik.ali 19
import com.spice.profitmandi.common.model.ProfitMandiConstants;
23019 ashik.ali 20
import com.spice.profitmandi.common.model.SchemeModel;
22859 ashik.ali 21
import com.spice.profitmandi.common.util.StringUtils;
22653 ashik.ali 22
import com.spice.profitmandi.dao.entity.catalog.RetailerScheme;
23
import com.spice.profitmandi.dao.entity.catalog.Scheme;
24
import com.spice.profitmandi.dao.entity.fofo.FofoLineItem;
22859 ashik.ali 25
import com.spice.profitmandi.dao.entity.fofo.FofoOrderItem;
22653 ashik.ali 26
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
22859 ashik.ali 27
import com.spice.profitmandi.dao.entity.fofo.SchemeInOut;
28
import com.spice.profitmandi.dao.entity.fofo.SchemeItem;
22653 ashik.ali 29
import com.spice.profitmandi.dao.enumuration.catalog.SchemeAmountType;
30
import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;
22859 ashik.ali 31
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
22653 ashik.ali 32
import com.spice.profitmandi.dao.repository.catalog.RetailerSchemeRepository;
33
import com.spice.profitmandi.dao.repository.catalog.SchemeRepository;
22859 ashik.ali 34
import com.spice.profitmandi.dao.repository.dtr.RetailerRepository;
23019 ashik.ali 35
import com.spice.profitmandi.dao.repository.fofo.FofoLineItemRepository;
36
import com.spice.profitmandi.dao.repository.fofo.FofoOrderItemRepository;
22653 ashik.ali 37
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
22859 ashik.ali 38
import com.spice.profitmandi.dao.repository.fofo.SchemeInOutRepository;
39
import com.spice.profitmandi.dao.repository.fofo.SchemeItemRepository;
22925 ashik.ali 40
import com.spice.profitmandi.service.inventory.OrderService;
22859 ashik.ali 41
import com.spice.profitmandi.service.wallet.WalletService;
22653 ashik.ali 42
 
22859 ashik.ali 43
import in.shop2020.model.v1.catalog.ItemType;
44
import in.shop2020.model.v1.order.WalletReferenceType;
45
 
22653 ashik.ali 46
@Component
47
public class SchemeServiceImpl implements SchemeService {
48
 
22859 ashik.ali 49
	private static final Logger LOGGER = LoggerFactory.getLogger(SchemeServiceImpl.class);
50
 
22653 ashik.ali 51
	@Autowired
52
	private InventoryItemRepository inventoryItemRepository;
53
 
54
	@Autowired
22925 ashik.ali 55
	private OrderService orderService;
22653 ashik.ali 56
 
57
	@Autowired
58
	private SchemeRepository schemeRepository;
59
 
60
	@Autowired
22859 ashik.ali 61
	private RetailerRepository retailerRepository;
62
 
63
	@Autowired
22653 ashik.ali 64
	private RetailerSchemeRepository retailerSchemeRepository;
65
 
66
	@Autowired
22859 ashik.ali 67
	private SchemeInOutRepository schemeInOutRepository;
22653 ashik.ali 68
 
69
	@Autowired
22859 ashik.ali 70
	private ItemRepository itemRepository;
22653 ashik.ali 71
 
22859 ashik.ali 72
	@Autowired
73
	private SchemeItemRepository schemeItemRepository;
74
 
75
	@Autowired
76
	private WalletService walletService;
77
 
23019 ashik.ali 78
	@Autowired
79
	private FofoOrderItemRepository fofoOrderItemRepository;
80
 
81
	@Autowired
82
	private FofoLineItemRepository fofoLineItemRepository;
83
 
22653 ashik.ali 84
	@Override
22859 ashik.ali 85
	public void saveScheme(int creatorId, CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException {
86
 
23019 ashik.ali 87
		this.validateCreateSchemeRequest(createSchemeRequest);
22653 ashik.ali 88
 
22859 ashik.ali 89
		Scheme scheme = this.toScheme(creatorId, createSchemeRequest);
90
 
23019 ashik.ali 91
		if(scheme.getStartDateTime().isAfter(scheme.getEndDateTime())){
92
			throw new ProfitMandiBusinessException(ProfitMandiConstants.START_DATE + ", " + ProfitMandiConstants.END_DATE, scheme.getStartDateTime() + ", " + scheme.getEndDateTime(), "SCHM_VE_1005");
22653 ashik.ali 93
		}
94
 
22859 ashik.ali 95
		this.validateItemIds(createSchemeRequest);
96
		schemeRepository.persist(scheme);
97
		if(!createSchemeRequest.isRetailerAll()){
98
			this.validateRetailerIds(createSchemeRequest);
99
			for(int retailerId : createSchemeRequest.getRetailerIds()){
100
				RetailerScheme retailerScheme = new RetailerScheme();
101
				retailerScheme.setRetailerId(retailerId);
102
				retailerScheme.setSchemeId(scheme.getId());
103
				retailerSchemeRepository.persist(retailerScheme);
104
			}
22653 ashik.ali 105
		}
22859 ashik.ali 106
		for(int itemId : createSchemeRequest.getItemIds()){
107
			SchemeItem schemeItem = new SchemeItem();
108
			schemeItem.setSchemeId(scheme.getId());
109
			schemeItem.setItemId(itemId);
110
			schemeItemRepository.persist(schemeItem);
111
		}
112
 
22653 ashik.ali 113
	}
22859 ashik.ali 114
 
23019 ashik.ali 115
	private void validateCreateSchemeRequest(CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException{
116
		if(createSchemeRequest.getName() == null || createSchemeRequest.getName().isEmpty()){
117
			throw new ProfitMandiBusinessException(ProfitMandiConstants.NAME, createSchemeRequest.getName(), "SCHM_VE_1000");
118
		}
119
		if(createSchemeRequest.getAmount() <= 0){
120
			throw new ProfitMandiBusinessException(ProfitMandiConstants.AMOUNT, createSchemeRequest.getAmount(), "SCHM_VE_1001");
121
		}
122
 
123
		if(SchemeAmountType.valueOf(createSchemeRequest.getAmountType()) == SchemeAmountType.PERCENTAGE && createSchemeRequest.getAmount() > 100){
124
			throw new ProfitMandiBusinessException(ProfitMandiConstants.AMOUNT, createSchemeRequest.getAmount(), "SCHM_VE_1002");
125
		}
126
 
127
		if(createSchemeRequest.getStartDateTimeString() == null || createSchemeRequest.getStartDateTimeString().isEmpty()){
128
			throw new ProfitMandiBusinessException(ProfitMandiConstants.START_DATE, createSchemeRequest.getStartDateTimeString(), "SCHM_VE_1003");
129
		}
130
 
131
		if(createSchemeRequest.getEndDateTimeString() == null || createSchemeRequest.getStartDateTimeString().isEmpty()){
132
			throw new ProfitMandiBusinessException(ProfitMandiConstants.END_DATE, createSchemeRequest.getEndDateTimeString(), "SCHM_VE_1004");
133
		}
134
	}
135
 
22859 ashik.ali 136
	private Scheme toScheme(int creatorId, CreateSchemeRequest createSchemeRequest){
137
		Scheme scheme = new Scheme();
138
		scheme.setName(createSchemeRequest.getName());
139
		scheme.setDescription(createSchemeRequest.getDescription());
140
		scheme.setType(SchemeType.valueOf(createSchemeRequest.getType()));
141
		scheme.setAmountType(SchemeAmountType.valueOf(createSchemeRequest.getAmountType()));
142
		scheme.setAmount(createSchemeRequest.getAmount());
23019 ashik.ali 143
		scheme.setStartDateTime(StringUtils.toDateTime(createSchemeRequest.getStartDateTimeString(), DateTimePattern.DD_MM_YYYY_T_HH_MM_SS));
144
		scheme.setEndDateTime(StringUtils.toDateTime(createSchemeRequest.getEndDateTimeString(), DateTimePattern.DD_MM_YYYY_T_HH_MM_SS));
22859 ashik.ali 145
		scheme.setCreatedBy(creatorId);
146
		scheme.setRetailerAll(createSchemeRequest.isRetailerAll());
147
		return scheme;
148
	}
149
 
150
	private void validateRetailerIds(CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException{
22925 ashik.ali 151
		if(createSchemeRequest.getRetailerIds() == null || createSchemeRequest.getRetailerIds().isEmpty()){
152
			throw new ProfitMandiBusinessException(ProfitMandiConstants.RETAILER_ID, createSchemeRequest.getRetailerIds(), "SCHM_1001");
22859 ashik.ali 153
		}
22870 ashik.ali 154
		List<Integer> foundRetailerIds = retailerRepository.selectIdsByIds(createSchemeRequest.getRetailerIds());
22859 ashik.ali 155
		if(foundRetailerIds.size() != createSchemeRequest.getRetailerIds().size()){
156
			createSchemeRequest.getRetailerIds().removeAll(foundRetailerIds);
22925 ashik.ali 157
			throw new ProfitMandiBusinessException(ProfitMandiConstants.RETAILER_ID, createSchemeRequest.getRetailerIds(), "SCHM_1002");
22859 ashik.ali 158
		}
159
	}
160
 
161
	private void validateItemIds(CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException{
162
		if(createSchemeRequest.getItemIds() == null || createSchemeRequest.getItemIds().isEmpty()){
22925 ashik.ali 163
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ITEM_ID, createSchemeRequest.getItemIds(), "SCHM_1003");
22859 ashik.ali 164
		}
165
		List<Integer> foundItemIds = itemRepository.selectIdsByIdsAndType(createSchemeRequest.getItemIds(), ItemType.SERIALIZED);
166
		if(foundItemIds.size() != createSchemeRequest.getItemIds().size()){
167
			createSchemeRequest.getItemIds().removeAll(foundItemIds);
22925 ashik.ali 168
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ITEM_ID, createSchemeRequest.getItemIds(), "SCHM_1004");
22859 ashik.ali 169
		}
170
	}
171
 
172
	@Override
173
	public Scheme getSchemeById(int schemeId) throws ProfitMandiBusinessException {
174
		Scheme scheme = schemeRepository.selectById(schemeId);
175
		if(!scheme.isRetailerAll()){
23019 ashik.ali 176
			List<Integer> retailerIds = retailerSchemeRepository.selectRetailerIdsBySchemeId(scheme.getId());
177
			scheme.getRetailerIds().addAll(retailerIds);
22859 ashik.ali 178
		}
179
		List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(scheme.getId());
180
		scheme.setItemIds(new HashSet<>(itemIds));
181
		return scheme;
182
	}
23019 ashik.ali 183
 
184
	@Override
185
	public List<SchemeModel> getAllSchemeModels(LocalDateTime startDateTime, LocalDateTime endDateTime) {
186
		List<Scheme> schemes = schemeRepository.selectAllBetweenCreateTimestamp(startDateTime, endDateTime);
187
		Map<Integer, Scheme> schemeIdSchemeMap = this.toSchemeIdSchemeMap(schemes);
188
		List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIds(schemeIdSchemeMap.keySet());
189
		this.addItemIdsToSchemes(schemeItems, schemeIdSchemeMap);
190
		List<RetailerScheme> retailerSchemes = retailerSchemeRepository.selectBySchemeIds(schemeIdSchemeMap.keySet());
191
		this.addRetailerIdsToSchemes(retailerSchemes, schemeIdSchemeMap);
192
		return this.toSchemeModels(schemeIdSchemeMap);
193
	}
194
 
195
	private void addItemIdsToSchemes(List<SchemeItem> schemeItems, Map<Integer, Scheme> schemeIdSchemeMap){
196
		for(SchemeItem schemeItem : schemeItems){
197
			schemeIdSchemeMap.get(schemeItem.getSchemeId())
198
			.getItemIds()
199
			.add(schemeItem.getItemId());
200
		}
201
	}
202
 
203
	private void addRetailerIdsToSchemes(List<RetailerScheme> retailerSchemes, Map<Integer, Scheme> schemeIdSchemeMap){
204
		for(RetailerScheme retailerScheme : retailerSchemes){
205
			schemeIdSchemeMap.get(retailerScheme.getSchemeId())
206
			.getRetailerIds()
207
			.add(retailerScheme.getRetailerId());
208
		}
209
	}
210
 
211
	private List<SchemeModel> toSchemeModels(Map<Integer, Scheme> schemeIdSchemeMap){
212
		List<SchemeModel> schemeModels = new ArrayList<>();
213
		for(Map.Entry<Integer, Scheme> schemeIdSchemeEntry : schemeIdSchemeMap.entrySet()){
214
			schemeModels.add(this.toSchemeModel(schemeIdSchemeEntry.getValue()));
215
		}
216
		return schemeModels;
217
	}
218
 
219
	private SchemeModel toSchemeModel(Scheme scheme){
220
		SchemeModel schemeModel = new SchemeModel();
221
		schemeModel.setSchemeId(scheme.getId());
222
		schemeModel.setName(scheme.getName());
223
		schemeModel.setDescription(scheme.getDescription());
224
		schemeModel.setSchemeType(scheme.getType().toString());
225
		schemeModel.setAmountType(scheme.getAmountType().toString());
226
		schemeModel.setAmount(scheme.getAmount());
227
		schemeModel.setStartDateTime(StringUtils.toString(scheme.getStartDateTime()));
228
		schemeModel.setEndDateTime(StringUtils.toString(scheme.getEndDateTime()));
229
		schemeModel.setCreateTimestamp(StringUtils.toString(scheme.getCreateTimestamp()));
230
		schemeModel.setActiveTimestamp(StringUtils.toString(scheme.getActiveTimestamp()));
231
		schemeModel.setExpireTimestamp(StringUtils.toString(scheme.getExpireTimestamp()));
232
		schemeModel.setCreatedBy(scheme.getCreatedBy());
233
		schemeModel.setItemIds(scheme.getItemIds());
234
		schemeModel.setRetailerIds(scheme.getRetailerIds());
235
		return schemeModel;
236
	}
22653 ashik.ali 237
 
238
	@Override
239
	public void activeSchemeById(int schemeId) throws ProfitMandiBusinessException {
240
		Scheme scheme = schemeRepository.selectById(schemeId);
241
		if(scheme.getActiveTimestamp() != null){
22925 ashik.ali 242
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ACTIVE_TIMESTAMP, scheme.getActiveTimestamp(), "SCHM_1005");
22653 ashik.ali 243
		}
244
		if(scheme.getExpireTimestamp() != null){
22925 ashik.ali 245
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EXPIRE_TIMESTAMP, scheme.getExpireTimestamp(), "SCHM_1006");
22653 ashik.ali 246
		}
22859 ashik.ali 247
		scheme.setActiveTimestamp(LocalDateTime.now());
248
		schemeRepository.persist(scheme);
23019 ashik.ali 249
		if(scheme.getType() == SchemeType.IN){
250
			this.processPreviousPurchases(scheme);
251
		}else if(scheme.getType() == SchemeType.OUT){
252
			this.processPreviousSales(scheme);
253
		}
22653 ashik.ali 254
	}
23019 ashik.ali 255
 
256
	private void processPreviousPurchases(Scheme scheme) throws ProfitMandiBusinessException{
257
		List<InventoryItem> inventoryItems = inventoryItemRepository.selectBetweenDates(scheme.getStartDateTime(), LocalDateTime.now());
258
		List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(scheme.getId());
259
		List<InventoryItem> completedInventoryItems = this.toFilteredPurchaseCompletedInventoryItems(inventoryItems, itemIds, true);
260
 
261
		if(scheme.isRetailerAll()){
262
			for(InventoryItem inventoryItem : completedInventoryItems){
263
				float cashback = this.createSchemeInOut(scheme, inventoryItem);
264
				walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItem.getPurchaseId(), WalletReferenceType.SCHEME_IN, "Added for SCHEME_IN", cashback);
265
			}
266
		}else{
267
			List<Integer> retailerIds = retailerSchemeRepository.selectRetailerIdsBySchemeId(scheme.getId());
268
			for(InventoryItem inventoryItem : completedInventoryItems){
269
				if(retailerIds.contains(inventoryItem.getFofoId())){
270
					float cashback = this.createSchemeInOut(scheme, inventoryItem);
271
					walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItem.getPurchaseId(), WalletReferenceType.SCHEME_IN, "Added for SCHEME_IN", cashback);
272
				}
273
			}
274
		}
275
 
276
	}
277
 
278
 
279
 
23297 ashik.ali 280
	private Map<Integer, Integer> toInventoryItemIdFofoOrderIdMap(List<FofoLineItem> fofoLineItems, Map<Integer, FofoOrderItem> fofoOrderItemIdFofoOrderItemMap){
23019 ashik.ali 281
		Map<Integer, Integer> inventoryItemIdFofoOrderIdMap = new HashMap<>();
282
 
283
		for(FofoLineItem fofoLineItem : fofoLineItems){
284
			inventoryItemIdFofoOrderIdMap.put(
285
					fofoLineItem.getInventoryItemId(),
286
					fofoOrderItemIdFofoOrderItemMap.get(fofoLineItem.getFofoOrderItemId()).getOrderId());
287
		}
288
		return inventoryItemIdFofoOrderIdMap;
289
	}
290
 
291
	private void processPreviousSales(Scheme scheme) throws ProfitMandiBusinessException{
292
		List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectBetweenDates(scheme.getStartDateTime(), LocalDateTime.now());
293
 
294
		Map<Integer, FofoOrderItem> fofoOrderItemIdFofoOrderItemMap = this.toFofoOrderItemIdFofoOrderItemMap(fofoOrderItems);
22653 ashik.ali 295
 
23019 ashik.ali 296
		List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIdFofoOrderItemMap.keySet());
297
 
23297 ashik.ali 298
		Map<Integer, Integer> inventoryItemIdFofoOrderIdMap = this.toInventoryItemIdFofoOrderIdMap(fofoLineItems, fofoOrderItemIdFofoOrderItemMap);
23019 ashik.ali 299
 
300
		List<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIdFofoOrderIdMap.keySet());
301
 
302
		List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(scheme.getId());
303
 
304
		List<InventoryItem> completedInventoryItems = this.toFilteredPurchaseCompletedInventoryItems(inventoryItems, itemIds, false);
305
 
306
 
307
		if(scheme.isRetailerAll()){
308
			for(InventoryItem inventoryItem : completedInventoryItems){
309
				float cashback = this.createSchemeInOut(scheme, inventoryItem);
23297 ashik.ali 310
				walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItem.getPurchaseId(), WalletReferenceType.SCHEME_OUT, "Added for SCHEME_OUT", cashback);
23019 ashik.ali 311
			}
312
		}else{
313
			List<Integer> retailerIds = retailerSchemeRepository.selectRetailerIdsBySchemeId(scheme.getId());
314
			for(InventoryItem inventoryItem : completedInventoryItems){
315
				if(retailerIds.contains(inventoryItem.getFofoId())){
316
					float cashback = this.createSchemeInOut(scheme, inventoryItem);
23297 ashik.ali 317
					walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItemIdFofoOrderIdMap.get(inventoryItem.getId()), WalletReferenceType.SCHEME_OUT, "Added for SCHEME_OUT", cashback);
23019 ashik.ali 318
				}
319
			}
320
		}
321
	}
322
 
323
	private Map<Integer, FofoOrderItem> toFofoOrderItemIdFofoOrderItemMap(List<FofoOrderItem> fofoOrderItems){
324
		Map<Integer, FofoOrderItem> fofoOrderItemIdFofoOrderItemMap = new HashMap<>();
325
		for(FofoOrderItem fofoOrderItem : fofoOrderItems){
326
			fofoOrderItemIdFofoOrderItemMap.put(fofoOrderItem.getId(), fofoOrderItem);
327
		}
328
		return fofoOrderItemIdFofoOrderItemMap;
329
	}
330
 
331
	private List<InventoryItem> toFilteredPurchaseCompletedInventoryItems(List<InventoryItem> inventoryItems, List<Integer> itemIds, boolean purchase){
332
		List<InventoryItem> completedInventoryItems = new ArrayList<>();
333
		for(InventoryItem inventoryItem : inventoryItems){
334
			if(purchase && inventoryItem.getPurchase().getCompleteTimestamp() != null && itemIds.contains(inventoryItem.getItemId())){
335
				completedInventoryItems.add(inventoryItem);
23297 ashik.ali 336
			}else if(!purchase && itemIds.contains(inventoryItem.getItemId())){
337
				completedInventoryItems.add(inventoryItem);
23019 ashik.ali 338
			}
339
		}
340
		return completedInventoryItems;
341
	}
342
 
22653 ashik.ali 343
	@Override
344
	public void expireSchemeById(int schemeId) throws ProfitMandiBusinessException {
345
		Scheme scheme = schemeRepository.selectById(schemeId);
346
		if(scheme.getActiveTimestamp() == null){
22925 ashik.ali 347
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ACTIVE_TIMESTAMP, scheme.getActiveTimestamp(), "SCHM_1007");
22653 ashik.ali 348
		}
349
		if(scheme.getExpireTimestamp() != null){
22925 ashik.ali 350
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EXPIRE_TIMESTAMP, scheme.getExpireTimestamp(), "SCHM_1008");
22653 ashik.ali 351
		}
22859 ashik.ali 352
		scheme.setExpireTimestamp(LocalDateTime.now());
353
		schemeRepository.persist(scheme);
22653 ashik.ali 354
	}
22859 ashik.ali 355
 
23019 ashik.ali 356
	private Map<Integer, Scheme> toSchemeIdSchemeMap(List<Scheme> schemes){
357
		Map<Integer, Scheme> schemeIdSchemeMap = new HashMap<>();
22859 ashik.ali 358
		for(Scheme scheme : schemes){
23019 ashik.ali 359
			schemeIdSchemeMap.put(scheme.getId(), scheme);
22859 ashik.ali 360
		}
23019 ashik.ali 361
		return schemeIdSchemeMap;
22859 ashik.ali 362
	}
363
 
364
	private Set<Integer> inventoryItemSchemesMapToSchemeIds(Map<InventoryItem, Set<Scheme>> inventoryItemSchemesMap){
365
		Set<Integer> schemeIds = new HashSet<>();
366
		for(Map.Entry<InventoryItem, Set<Scheme>> inventoryItemSchemesEntry : inventoryItemSchemesMap.entrySet()){
367
			for(Scheme scheme : inventoryItemSchemesEntry.getValue()){
368
				schemeIds.add(scheme.getId());
369
			}
370
		}
371
		return schemeIds;
372
	}
373
 
374
	private Set<Integer> fofoLineItemSchemesMapToSchemeIds(Map<FofoOrderItem, Set<Scheme>> fofoLineItemSchemesMap){
375
		Set<Integer> schemeIds = new HashSet<>();
376
		for(Map.Entry<FofoOrderItem, Set<Scheme>> inventoryItemSchemesEntry : fofoLineItemSchemesMap.entrySet()){
377
			for(Scheme scheme : inventoryItemSchemesEntry.getValue()){
378
				schemeIds.add(scheme.getId());
379
			}
380
		}
381
		return schemeIds;
382
	}
383
 
384
	private Set<Integer> inventoryItemsToItemIds(List<InventoryItem> inventoryItems){
385
		Set<Integer> itemIds = new HashSet<>();
386
		for(InventoryItem inventoryItem : inventoryItems){
387
			itemIds.add(inventoryItem.getItemId());
388
		}
389
		return itemIds;
390
	}
391
 
392
	private Set<Integer> fofoOrderItemsToItemIds(List<FofoOrderItem> fofoOrderItems){
393
		Set<Integer> itemIds = new HashSet<>();
394
		for(FofoOrderItem fofoOrderItem : fofoOrderItems){
395
			itemIds.add(fofoOrderItem.getItemId());
396
		}
397
		return itemIds;
398
	}
399
 
400
	private Map<Integer, Set<Scheme>> toItemIdSchemesMap(List<SchemeItem> schemeItems, List<Scheme> schemes){
23019 ashik.ali 401
		Map<Integer, Scheme> schemeIdSchemesMap = this.toSchemeIdSchemeMap(schemes);
22859 ashik.ali 402
		Map<Integer, Set<Scheme>> itemIdSchemesMap = new HashMap<>();
403
		for(SchemeItem schemeItem : schemeItems){
404
			if(!itemIdSchemesMap.containsKey(schemeItem.getItemId())){
405
				Set<Scheme> schemesSet = new HashSet<>();
406
				schemesSet.add(schemeIdSchemesMap.get(schemeItem.getSchemeId()));
407
				itemIdSchemesMap.put(schemeItem.getItemId(), schemesSet);
408
			}else{
409
				itemIdSchemesMap.get(schemeItem.getItemId()).add(schemeIdSchemesMap.get(schemeItem.getSchemeId()));
410
			}
411
		}
412
		return itemIdSchemesMap;
413
	}
22653 ashik.ali 414
 
22859 ashik.ali 415
	private Map<InventoryItem, Set<Scheme>> toInventoryItemSchemesMap(List<Scheme> schemes, List<InventoryItem> inventoryItems){
416
		Set<Integer> schemeIds = new HashSet<>();
417
		for(Scheme scheme : schemes){
418
			schemeIds.add(scheme.getId());
419
		}
420
		Set<Integer> itemIds = this.inventoryItemsToItemIds(inventoryItems);
421
		List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIdsAndItemIds(schemeIds, itemIds);
22653 ashik.ali 422
 
22859 ashik.ali 423
		Map<Integer, Set<Scheme>> itemIdSchemesMap = this.toItemIdSchemesMap(schemeItems, schemes);
424
		Map<InventoryItem, Set<Scheme>> inventoryItemSchemsMap = new HashMap<>();
425
		for(InventoryItem inventoryItem : inventoryItems){
426
			if(itemIdSchemesMap.containsKey(inventoryItem.getItemId())){
427
				inventoryItemSchemsMap.put(inventoryItem, itemIdSchemesMap.get(inventoryItem.getItemId()));
428
			}
429
		}
430
		return inventoryItemSchemsMap;
431
	}
432
 
433
	private Map<FofoOrderItem, Set<Scheme>> toFofoOrderItemSchemesMap(List<Scheme> schemes, List<FofoOrderItem> fofoOrderItems){
434
		Set<Integer> schemeIds = new HashSet<>();
22653 ashik.ali 435
		for(Scheme scheme : schemes){
22859 ashik.ali 436
			schemeIds.add(scheme.getId());
437
		}
438
		Set<Integer> itemIds = this.fofoOrderItemsToItemIds(fofoOrderItems);
439
		List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIdsAndItemIds(schemeIds, itemIds);
440
 
441
		Map<FofoOrderItem, Set<Scheme>> fofoOrderItemSchemsMap = new HashMap<>();
442
 
443
		if(!schemeItems.isEmpty()){
444
			Map<Integer, Set<Scheme>> itemIdSchemesMap = this.toItemIdSchemesMap(schemeItems, schemes);
445
			for(FofoOrderItem fofoOrderItem : fofoOrderItems){
446
				if(itemIdSchemesMap.containsKey(fofoOrderItem.getItemId())){
447
					fofoOrderItemSchemsMap.put(fofoOrderItem, itemIdSchemesMap.get(fofoOrderItem.getItemId()));
448
				}
22653 ashik.ali 449
			}
450
		}
22859 ashik.ali 451
		return fofoOrderItemSchemsMap;
452
	}
453
 
454
	@Override
455
	public float processSchemeIn(int purchaseId, int retailerId) throws ProfitMandiBusinessException {
456
		List<Scheme> schemes = schemeRepository.selectActiveAll(SchemeType.IN, LocalDateTime.now());
457
		float totalCashback = 0;
458
		if(schemes.isEmpty()){
459
			return 0;
22653 ashik.ali 460
		}
22859 ashik.ali 461
		List<InventoryItem> inventoryItems = inventoryItemRepository.selectByPurchaseId(purchaseId);
462
		LOGGER.info("SchemeIn filter inventoryItems {}", inventoryItems);
22653 ashik.ali 463
 
22859 ashik.ali 464
		Map<InventoryItem, Set<Scheme>> inventoryItemSchemesMap = this.toInventoryItemSchemesMap(schemes, inventoryItems);
465
 
466
		if(inventoryItemSchemesMap.isEmpty()){
467
			return 0;
468
		}
469
		Map<InventoryItem, Set<Scheme>> notAllInventoryItemSchemesMap = new HashMap<>();
470
		Map<InventoryItem, Set<Scheme>> allInventoryItemSchemesMap = new HashMap<>();
471
 
472
		for(Map.Entry<InventoryItem, Set<Scheme>> inventoryItemSchemesEntry : inventoryItemSchemesMap.entrySet()){
473
			Set<Scheme> notAllSchemes = new HashSet<>();
474
			Set<Scheme> allSchemes = new HashSet<>();
475
			for(Scheme scheme : inventoryItemSchemesEntry.getValue()){
476
				if(!scheme.isRetailerAll()){
477
					notAllSchemes.add(scheme);
478
				}else{
479
					allSchemes.add(scheme);
480
				}
481
			}
482
			notAllInventoryItemSchemesMap.put(inventoryItemSchemesEntry.getKey(), notAllSchemes);
483
			allInventoryItemSchemesMap.put(inventoryItemSchemesEntry.getKey(), allSchemes);
484
		}
485
 
486
		for(Map.Entry<InventoryItem, Set<Scheme>> allInventoryItemSchemesEntry : allInventoryItemSchemesMap.entrySet()){
487
			for(Scheme scheme : allInventoryItemSchemesEntry.getValue()){
488
				float cashback = this.createSchemeInOut(scheme, allInventoryItemSchemesEntry.getKey());
489
				totalCashback = totalCashback + cashback;
490
			}
491
		}
492
 
493
		Set<Integer> schemeIds = this.inventoryItemSchemesMapToSchemeIds(notAllInventoryItemSchemesMap);
494
		if(!schemeIds.isEmpty()){
495
			List<Integer> foundSchemeIds = retailerSchemeRepository.selectSchemeIds(schemeIds, retailerId);
496
 
497
			for(Map.Entry<InventoryItem, Set<Scheme>> notAllInventoryItemSchemesEntry : notAllInventoryItemSchemesMap.entrySet()){
498
				for(Scheme scheme : notAllInventoryItemSchemesEntry.getValue()){
499
					if(foundSchemeIds.contains(scheme.getId())){
500
						float cashback = this.createSchemeInOut(scheme, notAllInventoryItemSchemesEntry.getKey());
501
						totalCashback = totalCashback + cashback;
22653 ashik.ali 502
					}
503
				}
504
			}
505
		}
22859 ashik.ali 506
		if(totalCashback > 0){
507
			walletService.addAmountToWallet(retailerId, purchaseId, WalletReferenceType.SCHEME_IN, "Added for SCHEME_IN", totalCashback);
508
		}
509
		return totalCashback;
22653 ashik.ali 510
	}
511
 
22859 ashik.ali 512
	private float createSchemeInOut(Scheme scheme, InventoryItem inventoryItem){
513
		float amount = this.getAmount(inventoryItem, scheme);
514
		SchemeInOut schemeInOut = new SchemeInOut();
515
		schemeInOut.setSchemeId(scheme.getId());
516
		schemeInOut.setInventoryItemId(inventoryItem.getId());
517
		schemeInOut.setAmount(amount);
518
		schemeInOutRepository.persist(schemeInOut);
519
		return amount;
520
	}
521
 
522
	private float getAmount(InventoryItem inventoryItem, Scheme scheme){
22653 ashik.ali 523
		float amount = 0;
22859 ashik.ali 524
		float totalTaxRate = inventoryItem.getIgstRate() + inventoryItem.getSgstRate() + inventoryItem.getCgstRate();
525
		float taxableSellingPrice = inventoryItem.getUnitPrice() / (1 + totalTaxRate / 100);
526
 
22653 ashik.ali 527
		if(scheme.getAmountType() == SchemeAmountType.PERCENTAGE){
22859 ashik.ali 528
			amount = taxableSellingPrice * scheme.getAmount() / 100;
22653 ashik.ali 529
		}else{
530
			amount = scheme.getAmount();
531
		}
22859 ashik.ali 532
		return amount;
22653 ashik.ali 533
	}
534
 
22859 ashik.ali 535
	private Map<Integer, InventoryItem> toInventoryItemIdInventoryItemMap(List<InventoryItem> inventoryItems){
536
		Map<Integer, InventoryItem> itemIdInventoryItemMap = new HashMap<>();
537
		for(InventoryItem inventoryItem : inventoryItems){
538
			itemIdInventoryItemMap.put(inventoryItem.getId(), inventoryItem);
22653 ashik.ali 539
		}
22859 ashik.ali 540
		return itemIdInventoryItemMap;
22653 ashik.ali 541
	}
22859 ashik.ali 542
 
543
 
544
	private Set<Integer> toInventoryItemIds(Set<FofoOrderItem> fofoOrderItems){
545
		Set<Integer> inventoryItemIds = new HashSet<>();
546
		//Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = this.toFofoOrderItemIdFofoLineItems(fofoOrderItems);
547
		for(FofoOrderItem fofoOrderItem : fofoOrderItems){
548
			for(FofoLineItem fofoLineItem : fofoOrderItem.getFofoLineItems()){
549
				inventoryItemIds.add(fofoLineItem.getInventoryItemId());
550
			}
551
		}
552
		return inventoryItemIds;
553
	}
22653 ashik.ali 554
 
555
	@Override
22859 ashik.ali 556
	public float processSchemeOut(int fofoOrderId, int retailerId) throws ProfitMandiBusinessException {
557
		List<Scheme> schemes = schemeRepository.selectActiveAll(SchemeType.OUT, LocalDateTime.now());
558
		LOGGER.info("Active Schemes {}", schemes);
559
		float totalCashback = 0;
560
		if(schemes.isEmpty()){
561
			return 0;
562
		}
22653 ashik.ali 563
 
22925 ashik.ali 564
		List<FofoOrderItem> fofoOrderItems = orderService.getByOrderId(fofoOrderId);
22859 ashik.ali 565
		//LOGGER.info("fofoOrderItems {}", fofoOrderItems);
566
 
567
		Map<FofoOrderItem, Set<Scheme>> fofoOrderItemSchemesMap = this.toFofoOrderItemSchemesMap(schemes, fofoOrderItems);
568
 
569
		LOGGER.info("fofoOrderItemSchemesMap {}", fofoOrderItemSchemesMap);
570
 
571
		if(fofoOrderItemSchemesMap.isEmpty()){
572
			return 0;
573
		}
574
 
575
		Set<Integer> inventoryItemIds = this.toInventoryItemIds(fofoOrderItemSchemesMap.keySet());
576
 
577
		List<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIds);
578
 
579
		Map<Integer, InventoryItem> inventoryItemIdInventoryItemMap = this.toInventoryItemIdInventoryItemMap(inventoryItems);
580
 
581
		Map<FofoOrderItem, Set<Scheme>> notAllFofoOrderItemSchemesMap = new HashMap<>();
582
		Map<FofoOrderItem, Set<Scheme>> allFofoOrderItemSchemesMap = new HashMap<>();
583
 
584
		for(Map.Entry<FofoOrderItem, Set<Scheme>> fofoOrderItemSchemesEntry : fofoOrderItemSchemesMap.entrySet()){
585
			Set<Scheme> notAllSchemes = new HashSet<>();
586
			Set<Scheme> allSchemes = new HashSet<>();
587
			for(Scheme scheme : fofoOrderItemSchemesEntry.getValue()){
588
				if(!scheme.isRetailerAll()){
589
					notAllSchemes.add(scheme);
590
				}else{
591
					allSchemes.add(scheme);
592
				}
22653 ashik.ali 593
			}
22859 ashik.ali 594
			notAllFofoOrderItemSchemesMap.put(fofoOrderItemSchemesEntry.getKey(), notAllSchemes);
595
			allFofoOrderItemSchemesMap.put(fofoOrderItemSchemesEntry.getKey(), allSchemes);
22653 ashik.ali 596
		}
22859 ashik.ali 597
 
598
		for(Map.Entry<FofoOrderItem, Set<Scheme>> allFofoOrderItemSchemesEntry : allFofoOrderItemSchemesMap.entrySet()){
599
			for(FofoLineItem fofoLineItem : allFofoOrderItemSchemesEntry.getKey().getFofoLineItems()){
600
				for(Scheme scheme : allFofoOrderItemSchemesEntry.getValue()){
601
					float cashback = this.createSchemeInOut(scheme, inventoryItemIdInventoryItemMap.get(fofoLineItem.getInventoryItemId()));
602
					totalCashback = totalCashback + cashback;
603
				}
604
			}
22653 ashik.ali 605
		}
606
 
22859 ashik.ali 607
		Set<Integer> schemeIds = this.fofoLineItemSchemesMapToSchemeIds(notAllFofoOrderItemSchemesMap);
608
 
609
		if(!schemeIds.isEmpty()){
610
			List<Integer> foundSchemeIds = retailerSchemeRepository.selectSchemeIds(schemeIds, retailerId);
611
 
612
			for(Map.Entry<FofoOrderItem, Set<Scheme>> notAllFofoOrderItemSchemesEntry : notAllFofoOrderItemSchemesMap.entrySet()){
613
				for(FofoLineItem fofoLineItem : notAllFofoOrderItemSchemesEntry.getKey().getFofoLineItems()){
614
					for(Scheme scheme : notAllFofoOrderItemSchemesEntry.getValue()){
615
						if(foundSchemeIds.contains(scheme.getId())){
616
							float cashback = this.createSchemeInOut(scheme, inventoryItemIdInventoryItemMap.get(fofoLineItem.getInventoryItemId()));
617
							totalCashback = totalCashback + cashback;
22653 ashik.ali 618
						}
619
					}
620
				}
22859 ashik.ali 621
			}	
22653 ashik.ali 622
		}
22859 ashik.ali 623
		if(totalCashback > 0){
624
			walletService.addAmountToWallet(retailerId, fofoOrderId, WalletReferenceType.SCHEME_OUT, "Added for SCHEME_OUT", totalCashback);
625
		}
626
		return totalCashback;
22653 ashik.ali 627
	}
23297 ashik.ali 628
 
22653 ashik.ali 629
}