Subversion Repositories SmartDukaan

Rev

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