Subversion Repositories SmartDukaan

Rev

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