Subversion Repositories SmartDukaan

Rev

Rev 30726 | Rev 30769 | 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
 
24307 amit.gupta 3
import com.spice.profitmandi.common.enumuration.ItemType;
29927 amit.gupta 4
import com.spice.profitmandi.common.enumuration.MessageType;
22653 ashik.ali 5
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
6
import com.spice.profitmandi.common.model.ProfitMandiConstants;
23019 ashik.ali 7
import com.spice.profitmandi.common.model.SchemeModel;
29927 amit.gupta 8
import com.spice.profitmandi.common.model.SendNotificationModel;
29584 manish 9
import com.spice.profitmandi.common.services.ReporticoService;
27395 amit.gupta 10
import com.spice.profitmandi.common.util.FormattingUtils;
22859 ashik.ali 11
import com.spice.profitmandi.common.util.StringUtils;
30121 amit.gupta 12
import com.spice.profitmandi.common.util.Utils;
23339 ashik.ali 13
import com.spice.profitmandi.dao.entity.catalog.Item;
22653 ashik.ali 14
import com.spice.profitmandi.dao.entity.catalog.Scheme;
29927 amit.gupta 15
import com.spice.profitmandi.dao.entity.fofo.*;
26498 amit.gupta 16
import com.spice.profitmandi.dao.entity.transaction.PriceDrop;
23527 ashik.ali 17
import com.spice.profitmandi.dao.enumuration.catalog.AmountType;
22653 ashik.ali 18
import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;
25111 amit.gupta 19
import com.spice.profitmandi.dao.enumuration.fofo.ScanType;
27377 amit.gupta 20
import com.spice.profitmandi.dao.enumuration.transaction.SchemePayoutStatus;
25503 amit.gupta 21
import com.spice.profitmandi.dao.model.CreateSchemeRequest;
22859 ashik.ali 22
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
22653 ashik.ali 23
import com.spice.profitmandi.dao.repository.catalog.SchemeRepository;
30454 amit.gupta 24
import com.spice.profitmandi.dao.repository.catalog.StateGstRateRepository;
23995 amit.gupta 25
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
23968 amit.gupta 26
import com.spice.profitmandi.dao.repository.dtr.RetailerRepository;
29927 amit.gupta 27
import com.spice.profitmandi.dao.repository.fofo.*;
26498 amit.gupta 28
import com.spice.profitmandi.dao.repository.transaction.PriceDropRepository;
29927 amit.gupta 29
import com.spice.profitmandi.service.NotificationService;
23798 amit.gupta 30
import com.spice.profitmandi.service.authentication.RoleManager;
26722 amit.gupta 31
import com.spice.profitmandi.service.inventory.PurchaseService;
22859 ashik.ali 32
import com.spice.profitmandi.service.wallet.WalletService;
33
import in.shop2020.model.v1.order.WalletReferenceType;
29927 amit.gupta 34
import org.apache.logging.log4j.LogManager;
35
import org.apache.logging.log4j.Logger;
36
import org.hibernate.Session;
37
import org.hibernate.SessionFactory;
38
import org.hibernate.query.Query;
39
import org.springframework.beans.factory.annotation.Autowired;
40
import org.springframework.beans.factory.annotation.Qualifier;
41
import org.springframework.cache.annotation.Cacheable;
42
import org.springframework.stereotype.Component;
22859 ashik.ali 43
 
29927 amit.gupta 44
import javax.persistence.criteria.CriteriaBuilder;
45
import javax.persistence.criteria.CriteriaQuery;
46
import javax.persistence.criteria.Predicate;
47
import javax.persistence.criteria.Root;
48
import java.text.MessageFormat;
49
import java.time.LocalDate;
50
import java.time.LocalDateTime;
51
import java.time.YearMonth;
52
import java.util.*;
53
import java.util.stream.Collectors;
54
 
22653 ashik.ali 55
@Component
56
public class SchemeServiceImpl implements SchemeService {
57
 
23568 govind 58
	private static final Logger LOGGER = LogManager.getLogger(SchemeServiceImpl.class);
23444 amit.gupta 59
 
22653 ashik.ali 60
	@Autowired
23781 ashik.ali 61
	@Qualifier("fofoInventoryItemRepository")
22653 ashik.ali 62
	private InventoryItemRepository inventoryItemRepository;
23444 amit.gupta 63
 
22653 ashik.ali 64
	@Autowired
27395 amit.gupta 65
	private ActivatedImeiRepository activatedImeiRepository;
27898 amit.gupta 66
 
27395 amit.gupta 67
	@Autowired
25503 amit.gupta 68
	private PartnerTypeChangeService partnerTypeChangeService;
69
 
70
	@Autowired
26722 amit.gupta 71
	private PurchaseService purchaseService;
72
 
73
	@Autowired
25043 amit.gupta 74
	private ScanRecordRepository scanRecordRepository;
23444 amit.gupta 75
 
22653 ashik.ali 76
	@Autowired
26332 amit.gupta 77
	private SessionFactory sessionFactory;
78
 
30121 amit.gupta 79
	private static final Set<Integer> tagIds = new HashSet<Integer>(Arrays.asList(4));
26722 amit.gupta 80
 
26332 amit.gupta 81
	@Autowired
22653 ashik.ali 82
	private SchemeRepository schemeRepository;
26684 amit.gupta 83
 
26498 amit.gupta 84
	@Autowired
85
	private PriceDropRepository priceDropRepository;
23444 amit.gupta 86
 
22653 ashik.ali 87
	@Autowired
23798 amit.gupta 88
	private RoleManager roleManager;
89
 
90
	@Autowired
22859 ashik.ali 91
	private RetailerRepository retailerRepository;
29927 amit.gupta 92
 
29584 manish 93
	@Autowired
94
	private ReporticoService reporticoService;
24562 amit.gupta 95
 
29927 amit.gupta 96
 
23995 amit.gupta 97
	@Autowired
98
	private TagListingRepository tagListingRepository;
23444 amit.gupta 99
 
22859 ashik.ali 100
	@Autowired
101
	private SchemeInOutRepository schemeInOutRepository;
23444 amit.gupta 102
 
22653 ashik.ali 103
	@Autowired
23781 ashik.ali 104
	@Qualifier("catalogItemRepository")
22859 ashik.ali 105
	private ItemRepository itemRepository;
23444 amit.gupta 106
 
22859 ashik.ali 107
	@Autowired
108
	private SchemeItemRepository schemeItemRepository;
23444 amit.gupta 109
 
22859 ashik.ali 110
	@Autowired
111
	private WalletService walletService;
23444 amit.gupta 112
 
23019 ashik.ali 113
	@Autowired
23339 ashik.ali 114
	private PurchaseRepository purchaseRepository;
23444 amit.gupta 115
 
23344 ashik.ali 116
	@Autowired
23365 ashik.ali 117
	private FofoOrderRepository fofoOrderRepository;
23796 amit.gupta 118
 
22653 ashik.ali 119
	@Override
22859 ashik.ali 120
	public void saveScheme(int creatorId, CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException {
23444 amit.gupta 121
 
23019 ashik.ali 122
		this.validateCreateSchemeRequest(createSchemeRequest);
23444 amit.gupta 123
 
22859 ashik.ali 124
		Scheme scheme = this.toScheme(creatorId, createSchemeRequest);
23444 amit.gupta 125
 
126
		if (scheme.getStartDateTime().isAfter(scheme.getEndDateTime())) {
127
			throw new ProfitMandiBusinessException(
128
					ProfitMandiConstants.START_DATE + ", " + ProfitMandiConstants.END_DATE,
129
					scheme.getStartDateTime() + ", " + scheme.getEndDateTime(), "SCHM_VE_1005");
22653 ashik.ali 130
		}
23444 amit.gupta 131
 
26332 amit.gupta 132
		// this.validateItemIds(createSchemeRequest);
22859 ashik.ali 133
		schemeRepository.persist(scheme);
30121 amit.gupta 134
		for (int catalogId : createSchemeRequest.getCatalogIds()) {
22859 ashik.ali 135
			SchemeItem schemeItem = new SchemeItem();
136
			schemeItem.setSchemeId(scheme.getId());
30121 amit.gupta 137
			schemeItem.setCatalogId(catalogId);
22859 ashik.ali 138
			schemeItemRepository.persist(schemeItem);
139
		}
23444 amit.gupta 140
 
22653 ashik.ali 141
	}
23444 amit.gupta 142
 
143
	private void validateCreateSchemeRequest(CreateSchemeRequest createSchemeRequest)
144
			throws ProfitMandiBusinessException {
145
		if (createSchemeRequest.getName() == null || createSchemeRequest.getName().isEmpty()) {
146
			throw new ProfitMandiBusinessException(ProfitMandiConstants.NAME, createSchemeRequest.getName(),
147
					"SCHM_VE_1000");
23019 ashik.ali 148
		}
23444 amit.gupta 149
		if (createSchemeRequest.getAmount() <= 0) {
150
			throw new ProfitMandiBusinessException(ProfitMandiConstants.AMOUNT, createSchemeRequest.getAmount(),
151
					"SCHM_VE_1001");
23019 ashik.ali 152
		}
23444 amit.gupta 153
 
25503 amit.gupta 154
		if (createSchemeRequest.getAmountType().equals(AmountType.PERCENTAGE)
23444 amit.gupta 155
				&& createSchemeRequest.getAmount() > 100) {
156
			throw new ProfitMandiBusinessException(ProfitMandiConstants.AMOUNT, createSchemeRequest.getAmount(),
157
					"SCHM_VE_1002");
23019 ashik.ali 158
		}
23444 amit.gupta 159
 
23886 amit.gupta 160
		if (createSchemeRequest.getStartDate() == null) {
23983 amit.gupta 161
			throw new ProfitMandiBusinessException(ProfitMandiConstants.START_DATE, createSchemeRequest.getStartDate(),
162
					"SCHM_VE_1003");
23019 ashik.ali 163
		}
23886 amit.gupta 164
		if (createSchemeRequest.getEndDate() == null) {
23983 amit.gupta 165
			throw new ProfitMandiBusinessException(ProfitMandiConstants.END_DATE, createSchemeRequest.getEndDate(),
166
					"SCHM_VE_1004");
23019 ashik.ali 167
		}
168
	}
23444 amit.gupta 169
 
30454 amit.gupta 170
	@Autowired
171
	StateGstRateRepository stateGstRateRepository;
23444 amit.gupta 172
 
29927 amit.gupta 173
 
23444 amit.gupta 174
	private void validateItemIds(CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException {
30121 amit.gupta 175
		if (createSchemeRequest.getCatalogIds() == null || createSchemeRequest.getCatalogIds().isEmpty()) {
176
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ITEM_ID, createSchemeRequest.getCatalogIds(),
23444 amit.gupta 177
					"SCHM_1003");
22859 ashik.ali 178
		}
30121 amit.gupta 179
		List<Integer> foundItemIds = itemRepository.selectIdsByIdsAndType(createSchemeRequest.getCatalogIds(),
23444 amit.gupta 180
				ItemType.SERIALIZED);
30121 amit.gupta 181
		if (foundItemIds.size() != createSchemeRequest.getCatalogIds().size()) {
182
			createSchemeRequest.getCatalogIds().removeAll(foundItemIds);
183
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ITEM_ID, createSchemeRequest.getCatalogIds(),
23444 amit.gupta 184
					"SCHM_1004");
22859 ashik.ali 185
		}
186
	}
23444 amit.gupta 187
 
22859 ashik.ali 188
	@Override
189
	public Scheme getSchemeById(int schemeId) throws ProfitMandiBusinessException {
190
		Scheme scheme = schemeRepository.selectById(schemeId);
30121 amit.gupta 191
		List<Integer> catalogIds = schemeItemRepository.selectCatalogIdsBySchemeId(scheme.getId());
192
		if (catalogIds.size() > 0) {
193
			List<Item> items = itemRepository.selectAllByCatalogIds(new HashSet<>(catalogIds));
194
			scheme.setCatalogStringMap(this.toCatalogStringMap(items));
23983 amit.gupta 195
		}
22859 ashik.ali 196
		return scheme;
197
	}
23444 amit.gupta 198
 
30121 amit.gupta 199
	public Map<Integer, String> toCatalogStringMap(List<Item> items) {
200
		Map<Integer, String> catalogMap = new HashMap<>();
23444 amit.gupta 201
		for (Item item : items) {
30121 amit.gupta 202
			if (!catalogMap.containsKey(item.getCatalogItemId())) {
203
				catalogMap.put(item.getCatalogItemId(), item.getItemDescriptionNoColor());
204
			}
23339 ashik.ali 205
		}
30121 amit.gupta 206
		return catalogMap;
23339 ashik.ali 207
	}
23444 amit.gupta 208
 
30121 amit.gupta 209
	private Set<Integer> schemeItemsToCatalogIds(List<SchemeItem> schemeItems) {
210
		Set<Integer> catalogId = new HashSet<>();
23444 amit.gupta 211
		for (SchemeItem schemeItem : schemeItems) {
30121 amit.gupta 212
			catalogId.add(schemeItem.getCatalogId());
23339 ashik.ali 213
		}
30121 amit.gupta 214
		return catalogId;
23339 ashik.ali 215
	}
23444 amit.gupta 216
 
23019 ashik.ali 217
	@Override
218
	public List<SchemeModel> getAllSchemeModels(LocalDateTime startDateTime, LocalDateTime endDateTime) {
219
		List<Scheme> schemes = schemeRepository.selectAllBetweenCreateTimestamp(startDateTime, endDateTime);
30121 amit.gupta 220
		Map<Integer, Scheme> schemeIdSchemeMap = schemes.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
23019 ashik.ali 221
		List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIds(schemeIdSchemeMap.keySet());
30121 amit.gupta 222
		Set<Integer> catalogIds = schemeItems.stream().map(x -> x.getCatalogId()).collect(Collectors.toSet());
223
		List<Item> items = itemRepository.selectAllByCatalogIds(catalogIds);
224
		Map<Integer, String> catalogStringMap = this.toCatalogStringMap(items);
225
		this.addCatalogIdsToSchemes(schemeItems, schemeIdSchemeMap, catalogStringMap);
23019 ashik.ali 226
		return this.toSchemeModels(schemeIdSchemeMap);
227
	}
23444 amit.gupta 228
 
29927 amit.gupta 229
	@Autowired
230
	NotificationService notificationService;
23444 amit.gupta 231
 
232
	private List<SchemeModel> toSchemeModels(Map<Integer, Scheme> schemeIdSchemeMap) {
23019 ashik.ali 233
		List<SchemeModel> schemeModels = new ArrayList<>();
23444 amit.gupta 234
		for (Map.Entry<Integer, Scheme> schemeIdSchemeEntry : schemeIdSchemeMap.entrySet()) {
23019 ashik.ali 235
			schemeModels.add(this.toSchemeModel(schemeIdSchemeEntry.getValue()));
236
		}
237
		return schemeModels;
238
	}
23444 amit.gupta 239
 
240
	private SchemeModel toSchemeModel(Scheme scheme) {
23019 ashik.ali 241
		SchemeModel schemeModel = new SchemeModel();
242
		schemeModel.setSchemeId(scheme.getId());
243
		schemeModel.setName(scheme.getName());
244
		schemeModel.setDescription(scheme.getDescription());
245
		schemeModel.setSchemeType(scheme.getType().toString());
246
		schemeModel.setAmountType(scheme.getAmountType().toString());
247
		schemeModel.setAmount(scheme.getAmount());
248
		schemeModel.setStartDateTime(StringUtils.toString(scheme.getStartDateTime()));
249
		schemeModel.setEndDateTime(StringUtils.toString(scheme.getEndDateTime()));
250
		schemeModel.setCreateTimestamp(StringUtils.toString(scheme.getCreateTimestamp()));
251
		schemeModel.setActiveTimestamp(StringUtils.toString(scheme.getActiveTimestamp()));
252
		schemeModel.setExpireTimestamp(StringUtils.toString(scheme.getExpireTimestamp()));
253
		schemeModel.setCreatedBy(scheme.getCreatedBy());
30121 amit.gupta 254
		schemeModel.setCatalogStringMap(scheme.getCatalogStringMap());
23019 ashik.ali 255
		schemeModel.setRetailerIds(scheme.getRetailerIds());
256
		return schemeModel;
257
	}
22653 ashik.ali 258
 
30121 amit.gupta 259
	private void addCatalogIdsToSchemes(List<SchemeItem> schemeItems, Map<Integer, Scheme> schemeIdSchemeMap,
260
										Map<Integer, String> catalogStringMap) {
29927 amit.gupta 261
		for (SchemeItem schemeItem : schemeItems) {
30121 amit.gupta 262
			Scheme scheme = schemeIdSchemeMap.get(schemeItem.getSchemeId());
263
			scheme.getCatalogStringMap().put(schemeItem.getCatalogId(), catalogStringMap.get(schemeItem.getCatalogId()));
29927 amit.gupta 264
		}
265
	}
266
 
22653 ashik.ali 267
	@Override
268
	public void activeSchemeById(int schemeId) throws ProfitMandiBusinessException {
269
		Scheme scheme = schemeRepository.selectById(schemeId);
23444 amit.gupta 270
		if (scheme.getActiveTimestamp() != null) {
271
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ACTIVE_TIMESTAMP, scheme.getActiveTimestamp(),
272
					"SCHM_1005");
22653 ashik.ali 273
		}
23444 amit.gupta 274
		if (scheme.getExpireTimestamp() != null) {
275
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EXPIRE_TIMESTAMP, scheme.getExpireTimestamp(),
276
					"SCHM_1006");
22653 ashik.ali 277
		}
22859 ashik.ali 278
		scheme.setActiveTimestamp(LocalDateTime.now());
29927 amit.gupta 279
		this.sendSchemeNotification(scheme);
280
 
281
 
25438 amit.gupta 282
		/*
283
		 * if (scheme.getType() == SchemeType.IN) {
284
		 * this.processPreviousPurchases(scheme); } else if (scheme.getType() ==
285
		 * SchemeType.OUT) { this.processPreviousSales(scheme); }
286
		 */
22653 ashik.ali 287
	}
23444 amit.gupta 288
 
29927 amit.gupta 289
	private void sendSchemeNotification(Scheme scheme) throws ProfitMandiBusinessException {
30726 amit.gupta 290
		if (Arrays.asList(SchemeType.SPECIAL_SUPPORT, SchemeType.ACTIVATION).contains(scheme.getType())) {
29927 amit.gupta 291
 
292
			SendNotificationModel sendNotificationModel = new SendNotificationModel();
29935 amit.gupta 293
			List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIds(Collections.singleton(scheme.getId()));
30121 amit.gupta 294
			Set<Integer> catalogIds = schemeItems.stream().map(x -> x.getCatalogId()).collect(Collectors.toSet());
295
			List<String> itemDescriptions = itemRepository.selectAllByCatalogIds(catalogIds).stream().filter(Utils.distinctByKey(Item::getCatalogItemId))
296
					.map(x -> x.getItemDescriptionNoColor()).collect(Collectors.toList());
30726 amit.gupta 297
			String titleTemplate = "%s of Rs.%s for %s";
298
			String schemeString = "Activation scheme";
299
			if (scheme.getType().equals(SchemeType.SPECIAL_SUPPORT)) {
300
				schemeString = "Special Support";
301
			}
29927 amit.gupta 302
 
303
			String message = "Duration from - " + FormattingUtils.formatDateMonth(scheme.getStartDateTime()) + " - " + FormattingUtils.formatDateMonth(scheme.getEndDateTime());
304
			sendNotificationModel.setCampaignName("activationscheme");
305
			sendNotificationModel.setUrl("https://app.smartdukaan.com/pages/home/scheme/" + scheme.getId());
306
			sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(1));
307
			sendNotificationModel.setMessage(message);
30726 amit.gupta 308
			sendNotificationModel.setTitle(String.format(titleTemplate, schemeString, FormattingUtils.formatDecimal(scheme.getAmount()), String.join(", ", itemDescriptions)));
29940 amit.gupta 309
			sendNotificationModel.setType("url");
29927 amit.gupta 310
			sendNotificationModel.setMessageType(MessageType.scheme);
311
			notificationService.sendNotificationToAll(sendNotificationModel);
312
		}
313
	}
314
 
22653 ashik.ali 315
	@Override
25069 amit.gupta 316
	public void expireSchemeById(int schemeId, LocalDateTime expiryTime) throws ProfitMandiBusinessException {
22653 ashik.ali 317
		Scheme scheme = schemeRepository.selectById(schemeId);
25111 amit.gupta 318
		if (scheme == null || scheme.getActiveTimestamp() == null) {
23444 amit.gupta 319
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ACTIVE_TIMESTAMP, scheme.getActiveTimestamp(),
320
					"SCHM_1007");
22653 ashik.ali 321
		}
23444 amit.gupta 322
		if (scheme.getExpireTimestamp() != null) {
323
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EXPIRE_TIMESTAMP, scheme.getExpireTimestamp(),
324
					"SCHM_1008");
22653 ashik.ali 325
		}
22859 ashik.ali 326
		scheme.setExpireTimestamp(LocalDateTime.now());
29231 amit.gupta 327
		if (expiryTime.isAfter(scheme.getEndDateTime())) {
28749 amit.gupta 328
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EXPIRE_TIMESTAMP, scheme.getExpireTimestamp(),
329
					"End Date cant be extended during expiry");
330
		}
25069 amit.gupta 331
		scheme.setEndDateTime(expiryTime);
22859 ashik.ali 332
		schemeRepository.persist(scheme);
22653 ashik.ali 333
	}
23444 amit.gupta 334
 
335
	private Map<Integer, Scheme> toSchemeIdSchemeMap(List<Scheme> schemes) {
23019 ashik.ali 336
		Map<Integer, Scheme> schemeIdSchemeMap = new HashMap<>();
23444 amit.gupta 337
		for (Scheme scheme : schemes) {
23019 ashik.ali 338
			schemeIdSchemeMap.put(scheme.getId(), scheme);
22859 ashik.ali 339
		}
23019 ashik.ali 340
		return schemeIdSchemeMap;
22859 ashik.ali 341
	}
23444 amit.gupta 342
 
30121 amit.gupta 343
	private Map<Integer, Set<Scheme>> toCatalogIdSchemesMap(List<SchemeItem> schemeItems, List<Scheme> schemes) {
30186 amit.gupta 344
		Map<Integer, Scheme> schemesMap = schemes.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
345
		Map<Integer, Set<Scheme>> catalogSchemesMap = new HashMap<>();
23444 amit.gupta 346
		for (SchemeItem schemeItem : schemeItems) {
30186 amit.gupta 347
			if (!catalogSchemesMap.containsKey(schemeItem.getCatalogId())) {
348
				catalogSchemesMap.put(schemeItem.getCatalogId(), new HashSet<>());
22859 ashik.ali 349
			}
30186 amit.gupta 350
			Set<Scheme> schemesSet = catalogSchemesMap.get(schemeItem.getCatalogId());
351
			schemesSet.add(schemesMap.get(schemeItem.getSchemeId()));
22859 ashik.ali 352
		}
30186 amit.gupta 353
		return catalogSchemesMap;
22859 ashik.ali 354
	}
22653 ashik.ali 355
 
23444 amit.gupta 356
	private Map<InventoryItem, Set<Scheme>> toInventoryItemSchemesMap(List<Scheme> schemes,
29927 amit.gupta 357
																	  List<InventoryItem> inventoryItems) {
30186 amit.gupta 358
		Set<Integer> schemeIds = schemes.stream().map(x -> x.getId()).collect(Collectors.toSet());
30150 amit.gupta 359
		Set<Integer> itemIds = inventoryItems.stream().map(x -> x.getItemId()).collect(Collectors.toSet());
360
		Set<Integer> catalogIds = itemRepository.selectByIds(itemIds).stream().map(x -> x.getCatalogItemId()).collect(Collectors.toSet());
361
		List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIdsAndCatalogIds(schemeIds, catalogIds);
23444 amit.gupta 362
 
30186 amit.gupta 363
		Map<Integer, Set<Scheme>> catalogIdSchemesMap = this.toCatalogIdSchemesMap(schemeItems, schemes);
30191 amit.gupta 364
		Map<InventoryItem, Set<Scheme>> inventoryItemSchemesMap = new HashMap<>();
23444 amit.gupta 365
		for (InventoryItem inventoryItem : inventoryItems) {
30191 amit.gupta 366
			LOGGER.info("inventoryItem {}", inventoryItem);
367
			LOGGER.info("inventoryItem.getItem() {}", inventoryItem.getItem());
368
			LOGGER.info("catalogIdSchemesMap {}", catalogIdSchemesMap);
30186 amit.gupta 369
			if (catalogIdSchemesMap.containsKey(inventoryItem.getItem().getCatalogItemId())) {
30191 amit.gupta 370
				inventoryItemSchemesMap.put(inventoryItem, catalogIdSchemesMap.get(inventoryItem.getItem().getCatalogItemId()));
22859 ashik.ali 371
			}
372
		}
30191 amit.gupta 373
		return inventoryItemSchemesMap;
22859 ashik.ali 374
	}
23444 amit.gupta 375
 
22859 ashik.ali 376
	@Override
23365 ashik.ali 377
	public void processSchemeIn(int purchaseId, int retailerId) throws ProfitMandiBusinessException {
23369 ashik.ali 378
		LOGGER.info("Trying to process SchemeIn with purchaseId [{}] and retailerId [{}]", purchaseId, retailerId);
23344 ashik.ali 379
		Purchase purchase = purchaseRepository.selectByIdAndFofoId(purchaseId, retailerId);
29231 amit.gupta 380
		// TODO - SCHEME
381
		PartnerType partnerType = partnerTypeChangeService.getTypeOnMonth(retailerId,
382
				YearMonth.from(purchase.getCreateTimestamp()));
383
		// PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(retailerId,
384
		// purchase.getCreateTimestamp().toLocalDate());
385
 
386
		List<Scheme> schemes = schemeRepository.selectActiveAll(Arrays.asList(SchemeType.IN), partnerType,
27898 amit.gupta 387
				purchase.getCreateTimestamp(), false);
388
		float totalCashback = 0;
389
		if (schemes.isEmpty()) {
390
			return;
391
		}
392
		List<InventoryItem> inventoryItems = inventoryItemRepository.selectByPurchaseId(purchaseId);
26332 amit.gupta 393
 
27898 amit.gupta 394
		Set<Integer> itemIds = inventoryItems.stream().map(x -> x.getItemId()).collect(Collectors.toSet());
30191 amit.gupta 395
		Map<Integer, Item> itemsMap = itemRepository.selectByIds(itemIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
396
		inventoryItems.stream().forEach(x -> x.setItem(itemsMap.get(x.getItemId())));
397
 
27898 amit.gupta 398
		LocalDateTime billingDate = purchaseService.getBillingDateOfPurchase(purchaseId);
399
		Set<Integer> itemIdsSet = tagListingRepository.selectByItemIdsAndTagIds(itemIds, tagIds).stream()
400
				.filter(x -> x.getEolDate() == null || x.getEolDate().isAfter(billingDate)).map(x -> x.getItemId())
401
				.collect(Collectors.toSet());
402
		// Only consider inventory items that were not returned
403
		inventoryItems = inventoryItems.stream().filter(x -> itemIdsSet.contains(x.getItemId()))
404
				.filter(x -> !x.getLastScanType().equals(ScanType.PURCHASE_RET_BAD))
405
				.filter(x -> !x.getLastScanType().equals(ScanType.PURCHASE_RET)).collect(Collectors.toList());
406
		LOGGER.info(inventoryItems);
407
		if (inventoryItems.size() == 0)
408
			return;
409
		Map<InventoryItem, Set<Scheme>> inventoryItemSchemesMap = this.toInventoryItemSchemesMap(schemes,
410
				inventoryItems);
23444 amit.gupta 411
 
27898 amit.gupta 412
		if (inventoryItemSchemesMap.isEmpty()) {
413
			return;
414
		}
415
		Map<InventoryItem, Set<Scheme>> allInventoryItemSchemesMap = new HashMap<>();
23444 amit.gupta 416
 
27898 amit.gupta 417
		for (Map.Entry<InventoryItem, Set<Scheme>> inventoryItemSchemesEntry : inventoryItemSchemesMap.entrySet()) {
418
			Set<Scheme> allSchemes = new HashSet<>();
419
			for (Scheme scheme : inventoryItemSchemesEntry.getValue()) {
420
				allSchemes.add(scheme);
22859 ashik.ali 421
			}
27898 amit.gupta 422
			allInventoryItemSchemesMap.put(inventoryItemSchemesEntry.getKey(), allSchemes);
423
		}
23444 amit.gupta 424
 
27898 amit.gupta 425
		//
26722 amit.gupta 426
 
27898 amit.gupta 427
		int itemsCount = 0;
428
		for (Map.Entry<InventoryItem, Set<Scheme>> allInventoryItemSchemesEntry : allInventoryItemSchemesMap
429
				.entrySet()) {
430
			float inventoryItemCashback = 0;
431
			for (Scheme scheme : allInventoryItemSchemesEntry.getValue()) {
432
				InventoryItem inventoryItem = allInventoryItemSchemesEntry.getKey();
433
				float cashback = this.createSchemeInOut(scheme, inventoryItem);
434
				inventoryItemCashback += cashback;
22859 ashik.ali 435
			}
27898 amit.gupta 436
			if (inventoryItemCashback > 0) {
437
				totalCashback += inventoryItemCashback;
438
				itemsCount++;
23508 amit.gupta 439
			}
22653 ashik.ali 440
		}
27898 amit.gupta 441
 
442
		LOGGER.info("Items count for purchase id {} is {}", purchaseId, itemsCount);
443
		if (itemsCount > 0) {
444
			walletService.addAmountToWallet(
445
					retailerId, purchaseId, WalletReferenceType.SCHEME_IN, "Added for SCHEME IN against invoice "
446
							+ purchase.getPurchaseReference() + " (total " + itemsCount + " pcs)",
447
					totalCashback, purchase.getCreateTimestamp());
448
			LOGGER.info("Added Rs.{} for SCHEME IN against invoice {} total pcs({}) {}", totalCashback,
449
					purchase.getPurchaseReference(), itemsCount);
450
			purchase.setCashback(purchase.getCashback() + totalCashback);
451
			purchaseRepository.persist(purchase);
452
		}
22653 ashik.ali 453
	}
29927 amit.gupta 454
 
30454 amit.gupta 455
	private Scheme toScheme(int creatorId, CreateSchemeRequest createSchemeRequest) {
456
		Scheme scheme = new Scheme();
457
		scheme.setName(createSchemeRequest.getName());
458
		scheme.setDescription(createSchemeRequest.getDescription());
459
		scheme.setType(createSchemeRequest.getType());
460
		scheme.setAmountType(createSchemeRequest.getAmountType());
461
		scheme.setAmount(createSchemeRequest.getAmount());
462
		scheme.setPartnerType(createSchemeRequest.getPartnerType());
463
		scheme.setStartDateTime(createSchemeRequest.getStartDate());
464
		scheme.setEndDateTime(createSchemeRequest.getEndDate());
465
		scheme.setCreatedBy(creatorId);
466
		scheme.setCashback(createSchemeRequest.isCashback());
467
		scheme.setBasePlusGstCalc(createSchemeRequest.isBasePluseGstCalc());
468
		return scheme;
469
	}
470
 
29593 amit.gupta 471
	//Only in and activation margins are allowed to be rolled out more than twice
30454 amit.gupta 472
	private float createSchemeInOut(Scheme scheme, InventoryItem inventoryItem) throws ProfitMandiBusinessException {
29239 amit.gupta 473
		LOGGER.info("Scheme === {}", scheme);
29927 amit.gupta 474
		if ((scheme.getId() == 411 || scheme.getId() == 612) && inventoryItem.getCreateTimestamp().isAfter(LocalDate.of(2021, 12, 1).atStartOfDay())) {
29641 amit.gupta 475
			return 0;
476
		}
29231 amit.gupta 477
		List<SchemeInOut> sios = schemeInOutRepository.selectAllByType(scheme.getType(), inventoryItem.getId());
478
		float actualCredit = 0;
479
		if (sios.stream().filter(x -> x.getRolledBackTimestamp() == null && x.getSchemeId() == scheme.getId())
480
				.collect(Collectors.toList()).size() == 0) {
29927 amit.gupta 481
			sios = sios.stream().filter(x -> x.getRolledBackTimestamp() == null).collect(Collectors.toList());
29249 amit.gupta 482
			//Rejected Scheme for types INVESTMENT and ACTIVATION are considered rolledback only if the item billing is cancelled.
483
			float amountCredited = (float) sios.stream().mapToDouble(e -> e.getAmount()).sum();
29927 amit.gupta 484
 
29243 amit.gupta 485
			LOGGER.info("SIOS ===== {}", sios);
29231 amit.gupta 486
			float amountToCredit = this.getAmount(inventoryItem, scheme);
29593 amit.gupta 487
			//Activation and in scheme
30694 amit.gupta 488
			if (!scheme.getType().equals(SchemeType.IN) && !scheme.getType().equals(SchemeType.ACTIVATION) &&
489
					!scheme.getType().equals(SchemeType.SPECIAL_SUPPORT) && sios.size() > 0) {
29231 amit.gupta 490
 
29927 amit.gupta 491
				if (sios.size() > 1) {
29231 amit.gupta 492
					LOGGER.info("SAMESCHEMETYPE has already been credited twice for inventoryItem - {}", inventoryItem.getId());
493
					return 0;
494
				}
29927 amit.gupta 495
				if (amountToCredit > amountCredited + 1f) {
29231 amit.gupta 496
					for (SchemeInOut sio : sios) {
497
						sio.setRolledBackTimestamp(LocalDateTime.now());
498
						sio.setStatus(SchemePayoutStatus.REJECTED);
499
						sio.setStatusDescription("Partner Category upgraded, new entry added");
500
					}
501
					actualCredit = amountToCredit - amountCredited;
502
				} else {
503
					return 0;
504
				}
505
			} else {
506
				actualCredit = amountToCredit;
507
			}
29243 amit.gupta 508
			LOGGER.info("Actual Credit ==== {}", actualCredit);
29927 amit.gupta 509
 
24562 amit.gupta 510
			SchemeInOut schemeInOut = new SchemeInOut();
23443 amit.gupta 511
			schemeInOut.setSchemeId(scheme.getId());
512
			schemeInOut.setInventoryItemId(inventoryItem.getId());
27377 amit.gupta 513
			schemeInOut.setAmount(amountToCredit);
27433 amit.gupta 514
			schemeInOutRepository.persist(schemeInOut);
29231 amit.gupta 515
 
27898 amit.gupta 516
			if (scheme.getType().equals(SchemeType.ACTIVATION)) {
27377 amit.gupta 517
				schemeInOut.setStatus(SchemePayoutStatus.PENDING);
518
				schemeInOut.setStatusDescription("Activation pending for IMEI#" + inventoryItem.getSerialNumber());
519
				return 0;
27898 amit.gupta 520
			} else if (scheme.getType().equals(SchemeType.INVESTMENT)) {
521
				schemeInOut.setStatus(SchemePayoutStatus.PENDING);
522
				schemeInOut.setStatusDescription("Subject to investment days maintained");
523
				return 0;
27377 amit.gupta 524
			} else {
525
				schemeInOut.setStatus(SchemePayoutStatus.CREDITED);
27898 amit.gupta 526
				if (scheme.getType().equals(SchemeType.IN)) {
27713 amit.gupta 527
					schemeInOut.setStatusDescription("Credited for GRN of IMEI#" + inventoryItem.getSerialNumber());
29231 amit.gupta 528
				} else if (SchemeService.OUT_SCHEME_TYPES.contains(scheme.getType())) {
28737 amit.gupta 529
					schemeInOut.setStatusDescription("Credited for sale of IMEI#" + inventoryItem.getSerialNumber());
27713 amit.gupta 530
				}
27377 amit.gupta 531
				schemeInOut.setCreditTimestamp(LocalDateTime.now());
532
			}
23443 amit.gupta 533
		}
29231 amit.gupta 534
		return actualCredit;
22859 ashik.ali 535
	}
23444 amit.gupta 536
 
25049 amit.gupta 537
	// We are maintaining price drop after grn
30454 amit.gupta 538
	private float getAmount(InventoryItem inventoryItem, Scheme scheme) throws ProfitMandiBusinessException {
22653 ashik.ali 539
		float amount = 0;
25049 amit.gupta 540
		float dpForCalc = 0;
541
		float taxableSellingPrice = 0;
30454 amit.gupta 542
 
543
		float totalTaxRate = stateGstRateRepository.getTotalTaxRate(inventoryItem.getItemId());
23527 ashik.ali 544
		if (scheme.getAmountType() == AmountType.PERCENTAGE) {
24562 amit.gupta 545
			if (scheme.getType().equals(SchemeType.IN)) {
25049 amit.gupta 546
				dpForCalc = inventoryItem.getUnitPrice() - inventoryItem.getPriceDropAmount();
23995 amit.gupta 547
			} else {
548
				try {
26684 amit.gupta 549
					dpForCalc = Math.min(inventoryItem.getUnitPrice() - inventoryItem.getPriceDropAmount(),
26550 amit.gupta 550
							tagListingRepository.selectByItemId(inventoryItem.getItemId()).getSellingPrice());
24562 amit.gupta 551
				} catch (Exception e) {
23995 amit.gupta 552
					LOGGER.info("Could not find tag Listing entry in {}", inventoryItem.getItemId());
553
					e.printStackTrace();
554
				}
555
			}
25049 amit.gupta 556
			taxableSellingPrice = dpForCalc / (1 + totalTaxRate / 100);
22859 ashik.ali 557
			amount = taxableSellingPrice * scheme.getAmount() / 100;
25517 amit.gupta 558
			System.out.println(String.format("%d\t%s\t%d\t%d\t%s\t%s\t%s\t%s\t%f\t%f\t%f\t%f", inventoryItem.getId(),
25050 amit.gupta 559
					inventoryItem.getSerialNumber(), inventoryItem.getItemId(), scheme.getId(), scheme.getName(),
26332 amit.gupta 560
					scheme.getType(), scheme.getAmountType(), scheme.getPartnerType(), dpForCalc, taxableSellingPrice,
561
					scheme.getAmount(), amount));
23444 amit.gupta 562
		} else {
22653 ashik.ali 563
			amount = scheme.getAmount();
30454 amit.gupta 564
			if (scheme.isBasePlusGstCalc()) {
565
				amount = this.getReversalAmount(scheme, inventoryItem);
566
			}
25517 amit.gupta 567
			System.out.println(String.format("%d\t%s\t%d\t%d\t%s\t%s\t%s\t%s\t%f\t%f\t%d\t%f", inventoryItem.getId(),
25050 amit.gupta 568
					inventoryItem.getSerialNumber(), inventoryItem.getItemId(), scheme.getId(), scheme.getName(),
26332 amit.gupta 569
					scheme.getType(), scheme.getAmountType(), scheme.getPartnerType(), dpForCalc, taxableSellingPrice,
570
					0, amount));
22653 ashik.ali 571
		}
25049 amit.gupta 572
 
22859 ashik.ali 573
		return amount;
22653 ashik.ali 574
	}
23444 amit.gupta 575
 
30454 amit.gupta 576
	//Specifically for SchemeReversal
577
	private float getReversalAmount(Scheme scheme, InventoryItem inventoryItem) {
578
		float amount = scheme.getAmount();
579
		if (scheme.isBasePlusGstCalc()) {
580
			amount = (float) (amount / 1.18);
581
		}
582
		List<SchemeInOut> sios = schemeInOutRepository.selectAll(inventoryItem.getId());
583
		sios = sios.stream().filter(x -> x.getRolledBackTimestamp() == null).collect(Collectors.toList());
584
		List<Integer> schemeIds = sios.stream().map(x -> x.getSchemeId()).collect(Collectors.toList());
585
		List<Scheme> schemes = schemeRepository.selectBySchemeIds(schemeIds);
586
		float totalPaidPercentage = schemes.stream().filter(x -> x.getAmountType().equals(AmountType.PERCENTAGE)).map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x)).floatValue();
587
		return totalPaidPercentage;
588
	}
589
 
22653 ashik.ali 590
	@Override
30454 amit.gupta 591
	public float processSchemeOut(int fofoOrderId, int retailerId) throws ProfitMandiBusinessException {
592
		float totalCashback = 0;
23365 ashik.ali 593
		FofoOrder fofoOrder = fofoOrderRepository.selectByFofoIdAndOrderId(retailerId, fofoOrderId);
29231 amit.gupta 594
		// Process only if order is not cancelled
595
		if (fofoOrder.getCancelledTimestamp() == null) {
596
			// PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(retailerId,
597
			// fofoOrder.getCreateTimestamp().toLocalDate());
598
			// TODO - SCHEME
599
			PartnerType partnerType = partnerTypeChangeService.getTypeOnMonth(retailerId,
600
					YearMonth.from(fofoOrder.getCreateTimestamp()));
601
 
28969 amit.gupta 602
			List<ScanRecord> scanRecords = scanRecordRepository.selectAllByOrderId(fofoOrderId);
603
			Set<Integer> inventoryItemIds = scanRecords.stream().map(x -> x.getInventoryItemId())
604
					.collect(Collectors.toSet());
605
			Set<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIds).stream()
606
					.filter(x -> x.getSerialNumber() != null && !x.getSerialNumber().equals(""))
607
					.collect(Collectors.toSet());
608
			if (inventoryItems.size() == 0) {
30454 amit.gupta 609
				return 0;
22653 ashik.ali 610
			}
28969 amit.gupta 611
			Set<Integer> itemIds = inventoryItems.stream().map(x -> x.getItemId()).collect(Collectors.toSet());
29231 amit.gupta 612
 
613
			// Remove Items that are eol now.
28969 amit.gupta 614
			Set<Integer> itemIdsSet = tagListingRepository.selectByItemIdsAndTagIds(itemIds, tagIds).stream()
615
					.filter(x -> x.getEolDate() == null || x.getEolDate().isAfter(fofoOrder.getCreateTimestamp()))
616
					.map(x -> x.getItemId()).collect(Collectors.toSet());
617
			// Only consider inventory items that were not returned
618
			inventoryItems = inventoryItems.stream().filter(x -> itemIdsSet.contains(x.getItemId()))
619
					.collect(Collectors.toSet());
29231 amit.gupta 620
 
28969 amit.gupta 621
			if (inventoryItems.size() == 0) {
30454 amit.gupta 622
				return 0;
22859 ashik.ali 623
			}
29231 amit.gupta 624
 
28969 amit.gupta 625
			int count = 0;
29231 amit.gupta 626
 
627
			List<SchemeType> allOutSchemeTypes = new ArrayList<>();
628
			allOutSchemeTypes.addAll(Arrays.asList(SchemeType.ACTIVATION, SchemeType.INVESTMENT));
629
			allOutSchemeTypes.addAll(OUT_SCHEME_TYPES);
30454 amit.gupta 630
			allOutSchemeTypes.add(SchemeType.SPECIAL_SUPPORT);
29231 amit.gupta 631
			List<Scheme> allActiveSchemes = schemeRepository.selectActiveAll(allOutSchemeTypes, partnerType,
28969 amit.gupta 632
					fofoOrder.getCreateTimestamp(), false);
29231 amit.gupta 633
 
28969 amit.gupta 634
			for (InventoryItem inventoryItem : inventoryItems) {
635
				float itemCashback = 0;
636
				Set<Integer> schemeIds = new HashSet<>(
30121 amit.gupta 637
						schemeItemRepository.selectSchemeIdByCatalogId(inventoryItem.getItem().getCatalogItemId()));
29231 amit.gupta 638
				List<Scheme> itemActiveSchemes = allActiveSchemes.stream().filter(x -> schemeIds.contains(x.getId()))
28969 amit.gupta 639
						.collect(Collectors.toList());
30454 amit.gupta 640
				List<Scheme> supportSchemes = itemActiveSchemes.stream().filter(x -> x.getType().equals(SchemeType.SPECIAL_SUPPORT)).collect(Collectors.toList());
641
				itemActiveSchemes = itemActiveSchemes.stream().filter(x -> !x.getType().equals(SchemeType.SPECIAL_SUPPORT)).collect(Collectors.toList());
29231 amit.gupta 642
				for (Scheme scheme : itemActiveSchemes) {
29239 amit.gupta 643
					LOGGER.info("Scheme ==== {}", scheme);
28969 amit.gupta 644
					itemCashback += this.createSchemeInOut(scheme, inventoryItem);
645
				}
30454 amit.gupta 646
				if (supportSchemes.size() > 0) {
647
					this.processSpecialSupport(fofoOrder, supportSchemes, inventoryItem, partnerType, fofoOrder.getCreateTimestamp());
648
				}
29240 amit.gupta 649
				LOGGER.info("itemCashback ==== {}", itemCashback);
28969 amit.gupta 650
				if (itemCashback > 0) {
651
					count++;
652
					totalCashback += itemCashback;
653
				}
654
			}
655
			if (count > 0) {
29231 amit.gupta 656
				walletService.addAmountToWallet(
657
						retailerId, fofoOrderId, WalletReferenceType.SCHEME_OUT, "Sales margin for invoice number "
658
								+ fofoOrder.getInvoiceNumber() + ". Total " + count + " pc(s)",
28969 amit.gupta 659
						totalCashback, fofoOrder.getCreateTimestamp());
30454 amit.gupta 660
				fofoOrder.setCashback(totalCashback + fofoOrder.getCashback());
28969 amit.gupta 661
			}
22653 ashik.ali 662
		}
30454 amit.gupta 663
		return totalCashback;
22653 ashik.ali 664
	}
23444 amit.gupta 665
 
30463 amit.gupta 666
	@Override
667
	public float getSpecialSupportAmount(float supportAmount, PartnerType partnerType, LocalDate onDate, int catalogId) throws ProfitMandiBusinessException {
668
		int itemId = itemRepository.selectAllByCatalogItemId(catalogId).stream().findAny().get().getId();
669
		float totalTaxRate = stateGstRateRepository.getTotalTaxRate(itemId);
30572 amit.gupta 670
		return this.getSpecialSupportAmount(supportAmount, partnerType, onDate, catalogId, totalTaxRate);
671
	}
672
 
673
	@Override
674
	public float getSpecialSupportAmount(float supportAmount, PartnerType partnerType, LocalDate onDate, int catalogId, float taxRate) throws ProfitMandiBusinessException {
675
		float totalMargin = this.selectPercentageScheme(partnerType, onDate, catalogId, false, 0, 0).stream().collect(Collectors.summingDouble(x -> x.getAmount())).floatValue();
676
		float amountToCredit = supportAmount * (1 - totalMargin / (100 + taxRate));
30463 amit.gupta 677
		return amountToCredit;
678
	}
679
 
30454 amit.gupta 680
	private void processSpecialSupport(FofoOrder fofoOrder, List<Scheme> supportSchemes, InventoryItem inventoryItem, PartnerType partnerType, LocalDateTime saleDate) throws ProfitMandiBusinessException {
681
		int catalogId = inventoryItem.getItem().getCatalogItemId();
682
		float totalMargin = this.selectPercentageScheme(partnerType, saleDate.toLocalDate(), catalogId, false, 0, 0).stream().collect(Collectors.summingDouble(x -> x.getAmount())).floatValue();
683
		LOGGER.info("total percentage margin - {}", totalMargin);
684
		float totalTaxRate = 0;
685
		for (Scheme scheme : supportSchemes) {
686
			if (scheme.isBasePlusGstCalc()) {
687
				totalTaxRate = stateGstRateRepository.getTotalTaxRate(inventoryItem.getItemId());
688
			}
30766 amit.gupta 689
			float amountToCredit = scheme.getAmount() * (1 - (totalMargin / (100 + totalTaxRate)));
30454 amit.gupta 690
			List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectByScheme(scheme.getId(), inventoryItem.getId());
691
			SchemeInOut schemeInOut = schemeInOuts.stream().filter(x -> x.getRolledBackTimestamp() == null).findFirst().orElse(null);
692
			if (schemeInOut == null) {
693
				schemeInOut = new SchemeInOut();
694
				schemeInOut.setSchemeId(scheme.getId());
695
				schemeInOut.setInventoryItemId(inventoryItem.getId());
696
				schemeInOut.setCreateTimestamp(LocalDateTime.now());
697
				schemeInOut.setAmount(amountToCredit);
698
				schemeInOut.setStatus(SchemePayoutStatus.PENDING);
699
				schemeInOut.setStatusDescription("Special support, Activation pending for IMEI#" + inventoryItem.getSerialNumber());
700
				schemeInOutRepository.persist(schemeInOut);
701
			} else if (Double.valueOf(schemeInOut.getAmount()).intValue() != Double.valueOf(amountToCredit).intValue()) {
702
				schemeInOut.setStatus(SchemePayoutStatus.REJECTED);
703
				schemeInOut.setStatusDescription("Special support changed due to update in total margin");
704
				schemeInOut.setRolledBackTimestamp(LocalDateTime.now());
705
 
706
				SchemeInOut schemeInOutNew = new SchemeInOut();
707
				schemeInOutNew.setInventoryItemId(inventoryItem.getId());
708
				schemeInOutNew.setSchemeId(scheme.getId());
709
				schemeInOutNew.setCreateTimestamp(LocalDateTime.now());
710
				schemeInOutNew.setAmount(amountToCredit);
711
				if (schemeInOut.getStatus().equals(SchemePayoutStatus.CREDITED)) {
712
					schemeInOutNew.setStatus(SchemePayoutStatus.PENDING);
713
					schemeInOutNew.setStatusDescription("Special support, Activation pending for IMEI#" + inventoryItem.getSerialNumber());
714
					schemeInOutRepository.persist(schemeInOutNew);
715
				} else {
716
					schemeInOutNew.setStatus(SchemePayoutStatus.CREDITED);
717
					schemeInOutNew.setStatusDescription("Special support credited");
718
					schemeInOutRepository.persist(schemeInOutNew);
719
					walletService.addAmountToWallet(inventoryItem.getFofoId(), fofoOrder.getId(), WalletReferenceType.SPECIAL_SUPPORT,
720
							"Special support adjusted against overall margin gains for Imei - " + inventoryItem.getSerialNumber(), amountToCredit - schemeInOut.getAmount(),
721
							fofoOrder.getCreateTimestamp());
722
 
723
				}
724
			}
725
 
726
		}
727
 
728
	}
729
 
23508 amit.gupta 730
	@Override
23796 amit.gupta 731
	public void rollbackSchemes(List<Integer> inventoryItemIds, int rollbackReference, String rollbackReason)
732
			throws Exception {
23638 amit.gupta 733
		Set<Integer> inventoryItemIdSet = new HashSet<>(inventoryItemIds);
23508 amit.gupta 734
		float amountToRollback = 0;
735
		List<SchemeInOut> schemes = schemeInOutRepository.selectByInventoryItemIds(inventoryItemIdSet);
23796 amit.gupta 736
		for (SchemeInOut schemeInOut : schemes) {
23983 amit.gupta 737
			if (schemeInOut.getRolledBackTimestamp() == null) {
738
				schemeInOut.setRolledBackTimestamp(LocalDateTime.now());
29231 amit.gupta 739
				if (schemeInOut.getStatus() == null || schemeInOut.getStatus().equals(SchemePayoutStatus.CREDITED)) {
27377 amit.gupta 740
					amountToRollback += schemeInOut.getAmount();
741
				}
742
				schemeInOut.setStatus(SchemePayoutStatus.REJECTED);
743
				schemeInOut.setStatusDescription(rollbackReason);
23983 amit.gupta 744
			}
23508 amit.gupta 745
		}
23983 amit.gupta 746
		if (amountToRollback > 0) {
23638 amit.gupta 747
			int inventoryItemId = inventoryItemIds.get(0);
26498 amit.gupta 748
			InventoryItem ii = inventoryItemRepository.selectById(inventoryItemId);
749
			Integer fofoId = ii.getFofoId();
27898 amit.gupta 750
			// Purchase p = purchaseRepository.selectById(ii.getPurchaseId());
26684 amit.gupta 751
			// TODO//
26693 amit.gupta 752
			walletService.rollbackAmountFromWallet(fofoId, amountToRollback, ii.getPurchaseId(),
26498 amit.gupta 753
					WalletReferenceType.SCHEME_IN, rollbackReason, LocalDateTime.now());
23638 amit.gupta 754
		}
23508 amit.gupta 755
	}
23884 amit.gupta 756
 
23781 ashik.ali 757
	@Override
23796 amit.gupta 758
	public Map<String, Object> getSchemes(Set<Integer> roleIds, int offset, int limit)
759
			throws ProfitMandiBusinessException {
23781 ashik.ali 760
		Map<String, Object> map = new HashMap<>();
761
		List<Scheme> schemes = null;
762
		long size = 0;
23798 amit.gupta 763
		if (roleManager.isAdmin(roleIds)) {
23781 ashik.ali 764
			schemes = schemeRepository.selectAll(offset, limit);
765
			size = schemeRepository.selectAllCount();
23796 amit.gupta 766
		} else {
23781 ashik.ali 767
			schemes = schemeRepository.selectActiveAll(offset, limit);
768
			size = schemeRepository.selectAllActiveCount();
769
		}
770
		map.put("schemes", schemes);
771
		map.put("start", offset + 1);
772
		map.put("size", size);
23796 amit.gupta 773
		if (schemes.size() < limit) {
23781 ashik.ali 774
			map.put("end", offset + schemes.size());
23796 amit.gupta 775
		} else {
23781 ashik.ali 776
			map.put("end", offset + limit);
777
		}
778
		return map;
779
	}
23796 amit.gupta 780
 
23781 ashik.ali 781
	@Override
23796 amit.gupta 782
	public List<Scheme> getPaginatedSchemes(Set<Integer> roleIds, int offset, int limit)
783
			throws ProfitMandiBusinessException {
23781 ashik.ali 784
		LOGGER.info("requested offset=[{}], limit = [{}]", offset, limit);
785
		List<Scheme> schemes = null;
23798 amit.gupta 786
		if (roleManager.isAdmin(roleIds)) {
23781 ashik.ali 787
			schemes = schemeRepository.selectAll(offset, limit);
23796 amit.gupta 788
		} else {
23781 ashik.ali 789
			schemes = schemeRepository.selectActiveAll(offset, limit);
790
		}
791
		return schemes;
792
	}
23508 amit.gupta 793
 
23968 amit.gupta 794
	@Override
27898 amit.gupta 795
	// This is being called to reverse schemes while processing price Drop
24976 amit.gupta 796
	public void reverseSchemes(List<InventoryItem> inventoryItems, int priceDropId, String reversalReason)
26332 amit.gupta 797
			throws ProfitMandiBusinessException {
26498 amit.gupta 798
		PriceDrop priceDrop = priceDropRepository.selectById(priceDropId);
24976 amit.gupta 799
		Map<Integer, List<InventoryItem>> purchaseInventoryListMap = inventoryItems.stream()
800
				.collect(Collectors.groupingBy(InventoryItem::getPurchaseId, Collectors.toList()));
801
 
802
		for (Map.Entry<Integer, List<InventoryItem>> purchaseEntry : purchaseInventoryListMap.entrySet()) {
803
			float amountToCredit = 0;
804
			float amountToDebit = 0;
805
			int purchaseId = purchaseEntry.getKey();
806
			List<InventoryItem> purchaseInventoryItemList = purchaseEntry.getValue();
807
 
808
			Map<Integer, InventoryItem> inventoryItemsMap = purchaseInventoryItemList.stream()
809
					.collect(Collectors.toMap(x -> x.getId(), x -> x));
810
 
811
			List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectByInventoryItemIds(inventoryItemsMap.keySet());
27399 amit.gupta 812
			LOGGER.info("Scheme InOuts , {}", schemeInOuts);
27898 amit.gupta 813
			if (schemeInOuts.size() == 0) {
27400 amit.gupta 814
				continue;
815
			}
24976 amit.gupta 816
			List<Integer> schemeIds = schemeInOuts.stream().map(x -> x.getSchemeId()).collect(Collectors.toList());
817
			Map<Integer, Scheme> schemesMap = schemeRepository.selectBySchemeIds(schemeIds, 0, schemeIds.size())
818
					.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
819
			for (SchemeInOut schemeInOut : schemeInOuts) {
820
				InventoryItem ii = inventoryItemsMap.get(schemeInOut.getInventoryItemId());
821
				Scheme scheme = schemesMap.get(schemeInOut.getSchemeId());
822
				if (scheme.getAmountType().equals(AmountType.FIXED)) {
823
					continue;
23995 amit.gupta 824
				}
27713 amit.gupta 825
				if (scheme.getType().equals(SchemeType.IN) && schemeInOut.getRolledBackTimestamp() == null) {
24976 amit.gupta 826
					float newAmount = getAmount(ii, scheme);
827
					if (schemeInOut.getAmount() - newAmount >= 0.01f) {
828
						schemeInOut.setRolledBackTimestamp(LocalDateTime.now());
27898 amit.gupta 829
 
24976 amit.gupta 830
						SchemeInOut sioNew = new SchemeInOut();
831
						sioNew.setAmount(newAmount);
27713 amit.gupta 832
						sioNew.setStatus(schemeInOut.getStatus());
833
						sioNew.setStatusDescription(schemeInOut.getStatusDescription());
24976 amit.gupta 834
						sioNew.setInventoryItemId(schemeInOut.getInventoryItemId());
835
						sioNew.setSchemeId(schemeInOut.getSchemeId());
836
						schemeInOutRepository.persist(sioNew);
27713 amit.gupta 837
 
838
						schemeInOut.setStatus(SchemePayoutStatus.REJECTED);
839
						schemeInOut.setStatusDescription("Pricedrop processed, new entries added");
27898 amit.gupta 840
						// IF not credited then dont consider any credit/debit for that sio entry
841
						if (schemeInOut.getCreditTimestamp() != null) {
27713 amit.gupta 842
							amountToCredit += sioNew.getAmount();
843
							amountToDebit += schemeInOut.getAmount();
844
						}
24976 amit.gupta 845
					}
24562 amit.gupta 846
 
24976 amit.gupta 847
				}
23986 amit.gupta 848
			}
24976 amit.gupta 849
			int fofoId = inventoryItems.get(0).getFofoId();
850
			if (amountToDebit > 0) {
26684 amit.gupta 851
				walletService.addAmountToWallet(fofoId, purchaseId, WalletReferenceType.SCHEME_IN,
852
						MessageFormat.format(reversalReason, purchaseInventoryItemList.size()), -amountToDebit,
853
						priceDrop.getAffectedOn());
24976 amit.gupta 854
			}
855
			if (amountToCredit > 0) {
26403 amit.gupta 856
				walletService.addAmountToWallet(fofoId, purchaseId, WalletReferenceType.SCHEME_IN,
26684 amit.gupta 857
						MessageFormat.format(reversalReason, purchaseInventoryItemList.size()), amountToCredit,
858
						priceDrop.getAffectedOn());
24976 amit.gupta 859
			}
23968 amit.gupta 860
		}
861
	}
24562 amit.gupta 862
 
24264 amit.gupta 863
	@Override
29593 amit.gupta 864
	// Always being called from cancel order/bad return means no SCHEME IN is considered
24562 amit.gupta 865
	public void reverseSchemes(List<InventoryItem> inventoryItems, int reversalReference, String reversalReason,
29927 amit.gupta 866
							   List<SchemeType> schemeTypes) throws ProfitMandiBusinessException {
24264 amit.gupta 867
		Map<Integer, InventoryItem> inventoryItemsMap = inventoryItems.stream()
28419 tejbeer 868
				.collect(Collectors.toMap(x -> x.getId(), x -> x));
28417 tejbeer 869
		LOGGER.info("inventoryItems" + inventoryItems);
870
 
30261 amit.gupta 871
		Map<SchemeType, SchemeInOut> schemeTypeMap = new HashMap<>();
872
 
24264 amit.gupta 873
		List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectByInventoryItemIds(inventoryItemsMap.keySet());
28416 tejbeer 874
		LOGGER.info("schemeInOuts" + schemeInOuts);
28417 tejbeer 875
		float amountToRollback = 0;
28416 tejbeer 876
 
28417 tejbeer 877
		if (!schemeInOuts.isEmpty()) {
878
			List<Integer> schemeIds = schemeInOuts.stream().map(x -> x.getSchemeId()).collect(Collectors.toList());
879
			LOGGER.info("schemeIds" + schemeIds);
28416 tejbeer 880
 
28417 tejbeer 881
			Map<Integer, Scheme> schemesMap = schemeRepository.selectBySchemeIds(schemeIds, 0, schemeIds.size())
882
					.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
883
			for (SchemeInOut schemeInOut : schemeInOuts) {
884
				Scheme scheme = schemesMap.get(schemeInOut.getSchemeId());
29231 amit.gupta 885
				if (schemeTypes.contains(scheme.getType())) {
30261 amit.gupta 886
					schemeTypeMap.put(scheme.getType(), schemeInOut);
28417 tejbeer 887
					if (schemeInOut.getRolledBackTimestamp() == null) {
888
						schemeInOut.setRolledBackTimestamp(LocalDateTime.now());
889
						if (schemeInOut.getStatus().equals(SchemePayoutStatus.CREDITED)) {
890
							amountToRollback += schemeInOut.getAmount();
891
						}
892
						schemeInOut.setStatus(SchemePayoutStatus.REJECTED);
893
						schemeInOut.setStatusDescription(reversalReason);
27377 amit.gupta 894
					}
24264 amit.gupta 895
				}
896
			}
28417 tejbeer 897
 
24264 amit.gupta 898
		}
899
		int fofoId = inventoryItems.get(0).getFofoId();
29231 amit.gupta 900
		WalletReferenceType walletReferenceType = schemeTypes.containsAll(SchemeService.OUT_SCHEME_TYPES)
901
				? WalletReferenceType.SCHEME_OUT
902
				: (schemeTypes.contains(SchemeType.ACTIVATION) ? WalletReferenceType.ACTIVATION_SCHEME
30454 amit.gupta 903
				: (schemeTypes.contains(SchemeType.SPECIAL_SUPPORT)) ? WalletReferenceType.SPECIAL_SUPPORT : WalletReferenceType.INVESTMENT_PAYOUT);
27377 amit.gupta 904
		if (amountToRollback > 0) {
29231 amit.gupta 905
			// Mark appropriate reference of rollback investment margin
906
			if (schemeTypes.contains(SchemeType.INVESTMENT)) {
907
				reversalReference = Integer
30261 amit.gupta 908
						.parseInt(FormattingUtils.getYearMonth(schemeTypeMap.get(SchemeType.INVESTMENT).getCreditTimestamp().minusMonths(1)));
29231 amit.gupta 909
			}
27377 amit.gupta 910
			walletService.rollbackAmountFromWallet(fofoId, amountToRollback, reversalReference, walletReferenceType,
26498 amit.gupta 911
					reversalReason, LocalDateTime.now());
24268 amit.gupta 912
		}
24264 amit.gupta 913
	}
23968 amit.gupta 914
 
26332 amit.gupta 915
	@Override
916
	public double getTotalMargin(int itemId, PartnerType partnerType, LocalDateTime dateTime) {
917
		Session session = sessionFactory.getCurrentSession();
918
		CriteriaBuilder cb = session.getCriteriaBuilder();
919
		CriteriaQuery<Double> criteriaQuery = cb.createQuery(Double.class);
920
		Root<SchemeItem> schemeItem = criteriaQuery.from(SchemeItem.class);
921
		Root<Scheme> scheme = criteriaQuery.from(Scheme.class);
922
		Predicate schemePredicate = cb.equal(scheme.get(ProfitMandiConstants.AMOUNT_TYPE), AmountType.PERCENTAGE);
923
		Predicate lessThanPredicate = cb.lessThanOrEqualTo(scheme.get(ProfitMandiConstants.END_DATE_TIME), dateTime);
924
		Predicate greaterThanPredicate = cb.greaterThanOrEqualTo(scheme.get(ProfitMandiConstants.START_DATE_TIME),
925
				dateTime);
926
		Predicate joinPredicate = cb.equal(scheme.get("id"), schemeItem.get("schemeId"));
927
		Predicate schemeItemPredicate = cb.equal(schemeItem.get(ProfitMandiConstants.ITEM_ID), itemId);
928
		criteriaQuery.select(cb.sum(scheme.get(ProfitMandiConstants.AMOUNT))).where(schemePredicate, lessThanPredicate,
929
				greaterThanPredicate, schemeItemPredicate, joinPredicate);
930
 
931
		Query<Double> query = session.createQuery(criteriaQuery);
932
		return query.getSingleResult() + ProfitMandiConstants.SCHEME_INVESTMENT_MARGIN;
933
 
934
	}
935
 
26684 amit.gupta 936
	@Override
937
	@Cacheable(value = "itemSchemeCashback", cacheManager = "timeoutCacheManager")
30121 amit.gupta 938
	public Map<Integer, Float> getCatalogSchemeCashBack() {
26684 amit.gupta 939
		Map<Integer, Float> itemCashbackMap = new HashMap<>();
940
		Map<Integer, Scheme> cashbackSchemesMap = schemeRepository
30473 amit.gupta 941
				.selectActiveAll(Arrays.asList(SchemeType.ACTIVATION, SchemeType.SPECIAL_SUPPORT), PartnerType.ALL, LocalDateTime.now(), false)
29231 amit.gupta 942
				.stream().filter(x -> x.getAmountType().equals(AmountType.FIXED))
26684 amit.gupta 943
				.collect(Collectors.toMap(x -> x.getId(), x -> x));
26722 amit.gupta 944
		if (cashbackSchemesMap.size() > 0) {
26713 amit.gupta 945
			List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIds(cashbackSchemesMap.keySet());
946
			schemeItems.stream().forEach(x -> {
29864 amit.gupta 947
				float cashbackAmount = cashbackSchemesMap.get(x.getSchemeId()).getAmount();
30121 amit.gupta 948
				if (!itemCashbackMap.containsKey(x.getCatalogId())) {
949
					itemCashbackMap.put(x.getCatalogId(), cashbackAmount);
29864 amit.gupta 950
				} else {
30121 amit.gupta 951
					itemCashbackMap.put(x.getCatalogId(), itemCashbackMap.get(x.getCatalogId()) + cashbackAmount);
29864 amit.gupta 952
				}
26713 amit.gupta 953
			});
954
		}
26722 amit.gupta 955
		// A107FD Model needs to removed
26703 amit.gupta 956
		itemCashbackMap.remove(30211);
957
		itemCashbackMap.remove(30212);
958
		itemCashbackMap.remove(30213);
959
		itemCashbackMap.remove(30756);
26684 amit.gupta 960
		return itemCashbackMap;
961
	}
962
 
24562 amit.gupta 963
 
26802 tejbeer 964
	@Override
30121 amit.gupta 965
	public List<Scheme> selectSchemeByPartnerType(PartnerType partnerType, LocalDate onDate, int catalogId,
29927 amit.gupta 966
												  boolean isAdmin, int offset, int limit) throws ProfitMandiBusinessException {
26802 tejbeer 967
		Session session = sessionFactory.getCurrentSession();
30253 amit.gupta 968
		List<Predicate> andPredicates = new ArrayList<>();
26802 tejbeer 969
		CriteriaBuilder cb = session.getCriteriaBuilder();
970
		CriteriaQuery<Scheme> query = cb.createQuery(Scheme.class);
971
		Root<Scheme> scheme = query.from(Scheme.class);
30153 amit.gupta 972
		if (!partnerType.equals(PartnerType.ALL)) {
30121 amit.gupta 973
			List<PartnerType> pt = new ArrayList<>();
974
			pt.add(PartnerType.ALL);
975
			pt.add(partnerType);
30253 amit.gupta 976
			andPredicates.add(cb.in(scheme.get("partnerType")).value(pt));
30121 amit.gupta 977
		}
26802 tejbeer 978
		cb.desc(cb.isNull(scheme.get("expireTimestamp")));
30121 amit.gupta 979
		if (catalogId > 0) {
27898 amit.gupta 980
 
30121 amit.gupta 981
			List<Integer> schemeIds = schemeItemRepository.selectSchemeIdByCatalogId(catalogId);
27424 tejbeer 982
			LOGGER.info("schemeId" + schemeIds);
27898 amit.gupta 983
			if (schemeIds.isEmpty()) {
27424 tejbeer 984
				return new ArrayList<>();
985
			}
30253 amit.gupta 986
			andPredicates.add(cb.in(scheme.get("id")).value(schemeIds));
30121 amit.gupta 987
			if (onDate != null) {
30253 amit.gupta 988
				andPredicates.add(cb.greaterThan(scheme.get("endDateTime"), onDate.atStartOfDay()));
989
				andPredicates.add(cb.lessThanOrEqualTo(scheme.get("startDateTime"), onDate.atStartOfDay()));
26802 tejbeer 990
			}
991
		}
30253 amit.gupta 992
		if (!isAdmin) {
993
			andPredicates.add(cb.isNotNull(scheme.get("activeTimestamp")));
994
		}
995
		query.where(cb.and(andPredicates.toArray(new Predicate[0])));
26802 tejbeer 996
		query.orderBy(cb.desc(cb.function("isnull", Boolean.class, scheme.get("expireTimestamp"))));
30454 amit.gupta 997
		if (limit == 0) {
998
			return session.createQuery(query).setFirstResult(offset).getResultList();
999
		}
26802 tejbeer 1000
		return session.createQuery(query).setFirstResult(offset).setMaxResults(limit).getResultList();
1001
 
1002
	}
1003
 
1004
	@Override
30454 amit.gupta 1005
	public List<Scheme> selectPercentageScheme(PartnerType partnerType, LocalDate onDate, int catalogId,
1006
											   boolean isAdmin, int offset, int limit) throws ProfitMandiBusinessException {
1007
		List<Scheme> schemes = this.selectSchemeByPartnerType(partnerType, onDate, catalogId, isAdmin, offset, limit);
1008
		return schemes.stream().filter(x -> x.getAmountType().equals(AmountType.PERCENTAGE)).collect(Collectors.toList());
1009
	}
1010
 
1011
	@Override
27395 amit.gupta 1012
	public void processActivation() throws ProfitMandiBusinessException {
1013
		List<SchemeInOut> pendingPayouts = schemeInOutRepository.selectAllPending();
1014
		List<Integer> schemeIds = new ArrayList<>();
1015
		Set<Integer> inventoryIds = new HashSet<>();
27898 amit.gupta 1016
		for (SchemeInOut pendingPayout : pendingPayouts) {
27395 amit.gupta 1017
			schemeIds.add(pendingPayout.getSchemeId());
27440 amit.gupta 1018
		}
1019
		Map<Integer, Scheme> schemesMap = schemeRepository.selectBySchemeIds(schemeIds, 0, 0).stream()
30454 amit.gupta 1020
				.filter(x -> x.getType().equals(SchemeType.ACTIVATION) || x.getType().equals(SchemeType.SPECIAL_SUPPORT))
27898 amit.gupta 1021
				.collect(Collectors.toMap(x -> x.getId(), x -> x));
1022
		pendingPayouts = pendingPayouts.stream().filter(x -> schemesMap.get(x.getSchemeId()) != null)
1023
				.collect(Collectors.toList());
27440 amit.gupta 1024
 
27898 amit.gupta 1025
		for (SchemeInOut pendingPayout : pendingPayouts) {
27395 amit.gupta 1026
			inventoryIds.add(pendingPayout.getInventoryItemId());
1027
		}
27898 amit.gupta 1028
		Map<Integer, InventoryItem> inventoryItemMap = inventoryItemRepository.selectByIds(inventoryIds).stream()
1029
				.collect(Collectors.toMap(x -> x.getId(), x -> x));
1030
		Map<String, InventoryItem> serialNumberMap = inventoryItemMap.values().stream()
1031
				.collect(Collectors.toMap(x -> x.getSerialNumber(), x -> x));
1032
 
1033
		List<ActivatedImei> activatedImeis = activatedImeiRepository
30454 amit.gupta 1034
				.selectBySerialNumbers(new ArrayList<>(serialNumberMap.keySet())).stream().collect(Collectors.toList());
27898 amit.gupta 1035
 
1036
		Map<String, ActivatedImei> activatedImeiMap = activatedImeis.stream()
1037
				.collect(Collectors.toMap(x -> x.getSerialNumber(), x -> x));
1038
		for (SchemeInOut pendingPayout : pendingPayouts) {
27395 amit.gupta 1039
			InventoryItem ii = inventoryItemMap.get(pendingPayout.getInventoryItemId());
1040
			String serialNumber = ii.getSerialNumber();
1041
			ActivatedImei activatedImei = activatedImeiMap.get(serialNumber);
27898 amit.gupta 1042
			if (activatedImei == null) {
27395 amit.gupta 1043
				continue;
1044
			}
1045
			Scheme scheme = schemesMap.get(pendingPayout.getSchemeId());
30639 amit.gupta 1046
			if (scheme.isWithinRange(activatedImei.getActivationTimestamp())) {
27395 amit.gupta 1047
				int fofoId = ii.getFofoId();
27898 amit.gupta 1048
				// Get latest order Id
1049
				int orderId = scanRecordRepository.selectByInventoryItemId(ii.getId()).stream()
1050
						.filter(x -> x.getOrderId() > 0)
1051
						.sorted(Comparator.comparing(ScanRecord::getCreateTimestamp).reversed()).findFirst().get()
1052
						.getOrderId();
27395 amit.gupta 1053
				FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(orderId);
30454 amit.gupta 1054
				if (scheme.getType().equals(SchemeType.ACTIVATION)) {
1055
					walletService.addAmountToWallet(fofoId, orderId, WalletReferenceType.ACTIVATION_SCHEME,
1056
							"Activation margin for " + ii.getItem().getItemDescriptionNoColor() + ", Imei - " + serialNumber, pendingPayout.getAmount(),
1057
							fofoOrder.getCreateTimestamp());
1058
					pendingPayout.setStatusDescription("Activation margin credited");
1059
				} else {
1060
					walletService.addAmountToWallet(fofoId, orderId, WalletReferenceType.SPECIAL_SUPPORT,
1061
							"Special Support for " + ii.getItem().getItemDescriptionNoColor() + ", Imei - " + serialNumber, pendingPayout.getAmount(),
1062
							fofoOrder.getCreateTimestamp());
1063
					pendingPayout.setStatusDescription("Special support credited");
1064
 
1065
				}
27395 amit.gupta 1066
				pendingPayout.setCreditTimestamp(LocalDateTime.now());
1067
				pendingPayout.setStatus(SchemePayoutStatus.CREDITED);
1068
			} else {
1069
				pendingPayout.setStatus(SchemePayoutStatus.REJECTED);
27898 amit.gupta 1070
				pendingPayout.setRolledBackTimestamp(LocalDateTime.now());
1071
				;
1072
				pendingPayout.setStatusDescription(
1073
						"Rejected, activated on " + FormattingUtils.formatDate(activatedImei.getActivationTimestamp()));
27395 amit.gupta 1074
			}
1075
		}
1076
	}
26802 tejbeer 1077
 
22653 ashik.ali 1078
}