Subversion Repositories SmartDukaan

Rev

Rev 23796 | Rev 23840 | 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
 
23781 ashik.ali 11
import org.apache.logging.log4j.LogManager;
23568 govind 12
import org.apache.logging.log4j.Logger;
22653 ashik.ali 13
import org.springframework.beans.factory.annotation.Autowired;
23781 ashik.ali 14
import org.springframework.beans.factory.annotation.Qualifier;
22653 ashik.ali 15
import org.springframework.stereotype.Component;
16
 
22859 ashik.ali 17
import com.spice.profitmandi.common.enumuration.DateTimePattern;
22653 ashik.ali 18
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
22859 ashik.ali 19
import com.spice.profitmandi.common.model.CreateSchemeRequest;
22653 ashik.ali 20
import com.spice.profitmandi.common.model.ProfitMandiConstants;
23019 ashik.ali 21
import com.spice.profitmandi.common.model.SchemeModel;
22859 ashik.ali 22
import com.spice.profitmandi.common.util.StringUtils;
23339 ashik.ali 23
import com.spice.profitmandi.dao.entity.catalog.Item;
22653 ashik.ali 24
import com.spice.profitmandi.dao.entity.catalog.RetailerScheme;
25
import com.spice.profitmandi.dao.entity.catalog.Scheme;
23781 ashik.ali 26
import com.spice.profitmandi.dao.entity.dtr.Role;
22653 ashik.ali 27
import com.spice.profitmandi.dao.entity.fofo.FofoLineItem;
23365 ashik.ali 28
import com.spice.profitmandi.dao.entity.fofo.FofoOrder;
22859 ashik.ali 29
import com.spice.profitmandi.dao.entity.fofo.FofoOrderItem;
22653 ashik.ali 30
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
23339 ashik.ali 31
import com.spice.profitmandi.dao.entity.fofo.Purchase;
22859 ashik.ali 32
import com.spice.profitmandi.dao.entity.fofo.SchemeInOut;
33
import com.spice.profitmandi.dao.entity.fofo.SchemeItem;
23344 ashik.ali 34
import com.spice.profitmandi.dao.entity.transaction.Order;
23527 ashik.ali 35
import com.spice.profitmandi.dao.enumuration.catalog.AmountType;
22653 ashik.ali 36
import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;
23781 ashik.ali 37
import com.spice.profitmandi.dao.enumuration.dtr.RoleType;
22859 ashik.ali 38
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
22653 ashik.ali 39
import com.spice.profitmandi.dao.repository.catalog.RetailerSchemeRepository;
40
import com.spice.profitmandi.dao.repository.catalog.SchemeRepository;
22859 ashik.ali 41
import com.spice.profitmandi.dao.repository.dtr.RetailerRepository;
23781 ashik.ali 42
import com.spice.profitmandi.dao.repository.dtr.RoleRepository;
23019 ashik.ali 43
import com.spice.profitmandi.dao.repository.fofo.FofoLineItemRepository;
44
import com.spice.profitmandi.dao.repository.fofo.FofoOrderItemRepository;
23365 ashik.ali 45
import com.spice.profitmandi.dao.repository.fofo.FofoOrderRepository;
22653 ashik.ali 46
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
23339 ashik.ali 47
import com.spice.profitmandi.dao.repository.fofo.PurchaseRepository;
22859 ashik.ali 48
import com.spice.profitmandi.dao.repository.fofo.SchemeInOutRepository;
49
import com.spice.profitmandi.dao.repository.fofo.SchemeItemRepository;
23344 ashik.ali 50
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
23798 amit.gupta 51
import com.spice.profitmandi.service.authentication.RoleManager;
23365 ashik.ali 52
import com.spice.profitmandi.service.order.OrderService;
22859 ashik.ali 53
import com.spice.profitmandi.service.wallet.WalletService;
22653 ashik.ali 54
 
22859 ashik.ali 55
import in.shop2020.model.v1.catalog.ItemType;
56
import in.shop2020.model.v1.order.WalletReferenceType;
57
 
22653 ashik.ali 58
@Component
59
public class SchemeServiceImpl implements SchemeService {
60
 
23568 govind 61
	private static final Logger LOGGER = LogManager.getLogger(SchemeServiceImpl.class);
23444 amit.gupta 62
 
22653 ashik.ali 63
	@Autowired
23781 ashik.ali 64
	@Qualifier("fofoInventoryItemRepository")
22653 ashik.ali 65
	private InventoryItemRepository inventoryItemRepository;
23444 amit.gupta 66
 
22653 ashik.ali 67
	@Autowired
22925 ashik.ali 68
	private OrderService orderService;
23444 amit.gupta 69
 
22653 ashik.ali 70
	@Autowired
71
	private SchemeRepository schemeRepository;
23444 amit.gupta 72
 
22653 ashik.ali 73
	@Autowired
23798 amit.gupta 74
	private RoleManager roleManager;
75
 
76
	@Autowired
22859 ashik.ali 77
	private RetailerRepository retailerRepository;
23444 amit.gupta 78
 
22859 ashik.ali 79
	@Autowired
22653 ashik.ali 80
	private RetailerSchemeRepository retailerSchemeRepository;
23444 amit.gupta 81
 
22653 ashik.ali 82
	@Autowired
22859 ashik.ali 83
	private SchemeInOutRepository schemeInOutRepository;
23444 amit.gupta 84
 
22653 ashik.ali 85
	@Autowired
23781 ashik.ali 86
	@Qualifier("catalogItemRepository")
22859 ashik.ali 87
	private ItemRepository itemRepository;
23444 amit.gupta 88
 
22859 ashik.ali 89
	@Autowired
90
	private SchemeItemRepository schemeItemRepository;
23444 amit.gupta 91
 
22859 ashik.ali 92
	@Autowired
93
	private WalletService walletService;
23444 amit.gupta 94
 
23019 ashik.ali 95
	@Autowired
96
	private FofoOrderItemRepository fofoOrderItemRepository;
23444 amit.gupta 97
 
23019 ashik.ali 98
	@Autowired
99
	private FofoLineItemRepository fofoLineItemRepository;
23444 amit.gupta 100
 
23339 ashik.ali 101
	@Autowired
102
	private PurchaseRepository purchaseRepository;
23444 amit.gupta 103
 
23344 ashik.ali 104
	@Autowired
105
	private OrderRepository orderRepository;
23444 amit.gupta 106
 
23365 ashik.ali 107
	@Autowired
108
	private FofoOrderRepository fofoOrderRepository;
23796 amit.gupta 109
 
23781 ashik.ali 110
	@Autowired
111
	private RoleRepository roleRepository;
23444 amit.gupta 112
 
22653 ashik.ali 113
	@Override
22859 ashik.ali 114
	public void saveScheme(int creatorId, CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException {
23444 amit.gupta 115
 
23019 ashik.ali 116
		this.validateCreateSchemeRequest(createSchemeRequest);
23444 amit.gupta 117
 
22859 ashik.ali 118
		Scheme scheme = this.toScheme(creatorId, createSchemeRequest);
23444 amit.gupta 119
 
120
		if (scheme.getStartDateTime().isAfter(scheme.getEndDateTime())) {
121
			throw new ProfitMandiBusinessException(
122
					ProfitMandiConstants.START_DATE + ", " + ProfitMandiConstants.END_DATE,
123
					scheme.getStartDateTime() + ", " + scheme.getEndDateTime(), "SCHM_VE_1005");
22653 ashik.ali 124
		}
23444 amit.gupta 125
 
22859 ashik.ali 126
		this.validateItemIds(createSchemeRequest);
127
		schemeRepository.persist(scheme);
23444 amit.gupta 128
		if (!createSchemeRequest.isRetailerAll()) {
22859 ashik.ali 129
			this.validateRetailerIds(createSchemeRequest);
23444 amit.gupta 130
			for (int retailerId : createSchemeRequest.getRetailerIds()) {
22859 ashik.ali 131
				RetailerScheme retailerScheme = new RetailerScheme();
132
				retailerScheme.setRetailerId(retailerId);
133
				retailerScheme.setSchemeId(scheme.getId());
134
				retailerSchemeRepository.persist(retailerScheme);
135
			}
22653 ashik.ali 136
		}
23444 amit.gupta 137
		for (int itemId : createSchemeRequest.getItemIds()) {
22859 ashik.ali 138
			SchemeItem schemeItem = new SchemeItem();
139
			schemeItem.setSchemeId(scheme.getId());
140
			schemeItem.setItemId(itemId);
141
			schemeItemRepository.persist(schemeItem);
142
		}
23444 amit.gupta 143
 
22653 ashik.ali 144
	}
23444 amit.gupta 145
 
146
	private void validateCreateSchemeRequest(CreateSchemeRequest createSchemeRequest)
147
			throws ProfitMandiBusinessException {
148
		if (createSchemeRequest.getName() == null || createSchemeRequest.getName().isEmpty()) {
149
			throw new ProfitMandiBusinessException(ProfitMandiConstants.NAME, createSchemeRequest.getName(),
150
					"SCHM_VE_1000");
23019 ashik.ali 151
		}
23444 amit.gupta 152
		if (createSchemeRequest.getAmount() <= 0) {
153
			throw new ProfitMandiBusinessException(ProfitMandiConstants.AMOUNT, createSchemeRequest.getAmount(),
154
					"SCHM_VE_1001");
23019 ashik.ali 155
		}
23444 amit.gupta 156
 
23527 ashik.ali 157
		if (AmountType.valueOf(createSchemeRequest.getAmountType()) == AmountType.PERCENTAGE
23444 amit.gupta 158
				&& createSchemeRequest.getAmount() > 100) {
159
			throw new ProfitMandiBusinessException(ProfitMandiConstants.AMOUNT, createSchemeRequest.getAmount(),
160
					"SCHM_VE_1002");
23019 ashik.ali 161
		}
23444 amit.gupta 162
 
163
		if (createSchemeRequest.getStartDateTimeString() == null
164
				|| createSchemeRequest.getStartDateTimeString().isEmpty()) {
165
			throw new ProfitMandiBusinessException(ProfitMandiConstants.START_DATE,
166
					createSchemeRequest.getStartDateTimeString(), "SCHM_VE_1003");
23019 ashik.ali 167
		}
23444 amit.gupta 168
 
169
		if (createSchemeRequest.getEndDateTimeString() == null
170
				|| createSchemeRequest.getStartDateTimeString().isEmpty()) {
171
			throw new ProfitMandiBusinessException(ProfitMandiConstants.END_DATE,
172
					createSchemeRequest.getEndDateTimeString(), "SCHM_VE_1004");
23019 ashik.ali 173
		}
174
	}
23444 amit.gupta 175
 
176
	private Scheme toScheme(int creatorId, CreateSchemeRequest createSchemeRequest) {
22859 ashik.ali 177
		Scheme scheme = new Scheme();
178
		scheme.setName(createSchemeRequest.getName());
179
		scheme.setDescription(createSchemeRequest.getDescription());
180
		scheme.setType(SchemeType.valueOf(createSchemeRequest.getType()));
23527 ashik.ali 181
		scheme.setAmountType(AmountType.valueOf(createSchemeRequest.getAmountType()));
22859 ashik.ali 182
		scheme.setAmount(createSchemeRequest.getAmount());
23444 amit.gupta 183
		scheme.setStartDateTime(StringUtils.toDateTime(createSchemeRequest.getStartDateTimeString(),
184
				DateTimePattern.DD_MM_YYYY_T_HH_MM_SS));
185
		scheme.setEndDateTime(StringUtils.toDateTime(createSchemeRequest.getEndDateTimeString(),
186
				DateTimePattern.DD_MM_YYYY_T_HH_MM_SS));
22859 ashik.ali 187
		scheme.setCreatedBy(creatorId);
188
		scheme.setRetailerAll(createSchemeRequest.isRetailerAll());
189
		return scheme;
190
	}
23444 amit.gupta 191
 
192
	private void validateRetailerIds(CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException {
193
		if (createSchemeRequest.getRetailerIds() == null || createSchemeRequest.getRetailerIds().isEmpty()) {
194
			throw new ProfitMandiBusinessException(ProfitMandiConstants.RETAILER_ID,
195
					createSchemeRequest.getRetailerIds(), "SCHM_1001");
22859 ashik.ali 196
		}
22870 ashik.ali 197
		List<Integer> foundRetailerIds = retailerRepository.selectIdsByIds(createSchemeRequest.getRetailerIds());
23444 amit.gupta 198
		if (foundRetailerIds.size() != createSchemeRequest.getRetailerIds().size()) {
22859 ashik.ali 199
			createSchemeRequest.getRetailerIds().removeAll(foundRetailerIds);
23444 amit.gupta 200
			throw new ProfitMandiBusinessException(ProfitMandiConstants.RETAILER_ID,
201
					createSchemeRequest.getRetailerIds(), "SCHM_1002");
22859 ashik.ali 202
		}
203
	}
23444 amit.gupta 204
 
205
	private void validateItemIds(CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException {
206
		if (createSchemeRequest.getItemIds() == null || createSchemeRequest.getItemIds().isEmpty()) {
207
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ITEM_ID, createSchemeRequest.getItemIds(),
208
					"SCHM_1003");
22859 ashik.ali 209
		}
23444 amit.gupta 210
		List<Integer> foundItemIds = itemRepository.selectIdsByIdsAndType(createSchemeRequest.getItemIds(),
211
				ItemType.SERIALIZED);
212
		if (foundItemIds.size() != createSchemeRequest.getItemIds().size()) {
22859 ashik.ali 213
			createSchemeRequest.getItemIds().removeAll(foundItemIds);
23444 amit.gupta 214
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ITEM_ID, createSchemeRequest.getItemIds(),
215
					"SCHM_1004");
22859 ashik.ali 216
		}
217
	}
23444 amit.gupta 218
 
22859 ashik.ali 219
	@Override
220
	public Scheme getSchemeById(int schemeId) throws ProfitMandiBusinessException {
221
		Scheme scheme = schemeRepository.selectById(schemeId);
23444 amit.gupta 222
		if (!scheme.isRetailerAll()) {
23019 ashik.ali 223
			List<Integer> retailerIds = retailerSchemeRepository.selectRetailerIdsBySchemeId(scheme.getId());
224
			scheme.getRetailerIds().addAll(retailerIds);
22859 ashik.ali 225
		}
226
		List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(scheme.getId());
23339 ashik.ali 227
		List<Item> items = itemRepository.selectByIds(new HashSet<>(itemIds));
228
		scheme.setItemStringMap(this.toItemStringMap(items));
22859 ashik.ali 229
		return scheme;
230
	}
23444 amit.gupta 231
 
232
	public Map<Integer, String> toItemStringMap(List<Item> items) {
23339 ashik.ali 233
		Map<Integer, String> itemMap = new HashMap<>();
23444 amit.gupta 234
		for (Item item : items) {
23339 ashik.ali 235
			itemMap.put(item.getId(), this.getItemString(item));
236
		}
237
		return itemMap;
238
	}
23444 amit.gupta 239
 
240
	public String getItemString(Item item) {
23339 ashik.ali 241
		StringBuilder itemString = new StringBuilder();
23444 amit.gupta 242
		if (item.getBrand() != null && !item.getBrand().isEmpty()) {
23339 ashik.ali 243
			itemString.append(item.getBrand().trim());
244
		}
245
		itemString.append(" ");
23444 amit.gupta 246
		if (item.getModelName() != null && !item.getModelName().isEmpty()) {
23339 ashik.ali 247
			itemString.append(item.getModelName().trim());
248
		}
249
		itemString.append(" ");
23444 amit.gupta 250
		if (item.getModelNumber() != null && !item.getModelNumber().isEmpty()) {
23339 ashik.ali 251
			itemString.append(item.getModelNumber().trim());
252
		}
253
		itemString.append(" ");
23444 amit.gupta 254
		if (item.getColor() != null && !item.getColor().isEmpty()) {
23339 ashik.ali 255
			itemString.append(item.getColor().trim());
256
		}
257
		return itemString.toString();
258
	}
23444 amit.gupta 259
 
260
	private Set<Integer> schemeItemsToItemIds(List<SchemeItem> schemeItems) {
23339 ashik.ali 261
		Set<Integer> itemIds = new HashSet<>();
23444 amit.gupta 262
		for (SchemeItem schemeItem : schemeItems) {
23339 ashik.ali 263
			itemIds.add(schemeItem.getItemId());
264
		}
265
		return itemIds;
266
	}
23444 amit.gupta 267
 
23019 ashik.ali 268
	@Override
269
	public List<SchemeModel> getAllSchemeModels(LocalDateTime startDateTime, LocalDateTime endDateTime) {
270
		List<Scheme> schemes = schemeRepository.selectAllBetweenCreateTimestamp(startDateTime, endDateTime);
271
		Map<Integer, Scheme> schemeIdSchemeMap = this.toSchemeIdSchemeMap(schemes);
272
		List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIds(schemeIdSchemeMap.keySet());
23339 ashik.ali 273
		Set<Integer> itemIds = this.schemeItemsToItemIds(schemeItems);
274
		List<Item> items = itemRepository.selectByIds(itemIds);
275
		Map<Integer, String> itemStringMap = this.toItemStringMap(items);
276
		this.addItemIdsToSchemes(schemeItems, schemeIdSchemeMap, itemStringMap);
23019 ashik.ali 277
		List<RetailerScheme> retailerSchemes = retailerSchemeRepository.selectBySchemeIds(schemeIdSchemeMap.keySet());
278
		this.addRetailerIdsToSchemes(retailerSchemes, schemeIdSchemeMap);
279
		return this.toSchemeModels(schemeIdSchemeMap);
280
	}
23444 amit.gupta 281
 
282
	private void addItemIdsToSchemes(List<SchemeItem> schemeItems, Map<Integer, Scheme> schemeIdSchemeMap,
283
			Map<Integer, String> itemStringMap) {
284
		for (SchemeItem schemeItem : schemeItems) {
285
			schemeIdSchemeMap.get(schemeItem.getSchemeId()).getItemStringMap().put(schemeItem.getItemId(),
286
					itemStringMap.get(schemeItem.getItemId()));
23019 ashik.ali 287
		}
288
	}
23444 amit.gupta 289
 
290
	private void addRetailerIdsToSchemes(List<RetailerScheme> retailerSchemes, Map<Integer, Scheme> schemeIdSchemeMap) {
291
		for (RetailerScheme retailerScheme : retailerSchemes) {
292
			schemeIdSchemeMap.get(retailerScheme.getSchemeId()).getRetailerIds().add(retailerScheme.getRetailerId());
23019 ashik.ali 293
		}
294
	}
23444 amit.gupta 295
 
296
	private List<SchemeModel> toSchemeModels(Map<Integer, Scheme> schemeIdSchemeMap) {
23019 ashik.ali 297
		List<SchemeModel> schemeModels = new ArrayList<>();
23444 amit.gupta 298
		for (Map.Entry<Integer, Scheme> schemeIdSchemeEntry : schemeIdSchemeMap.entrySet()) {
23019 ashik.ali 299
			schemeModels.add(this.toSchemeModel(schemeIdSchemeEntry.getValue()));
300
		}
301
		return schemeModels;
302
	}
23444 amit.gupta 303
 
304
	private SchemeModel toSchemeModel(Scheme scheme) {
23019 ashik.ali 305
		SchemeModel schemeModel = new SchemeModel();
306
		schemeModel.setSchemeId(scheme.getId());
307
		schemeModel.setName(scheme.getName());
308
		schemeModel.setDescription(scheme.getDescription());
309
		schemeModel.setSchemeType(scheme.getType().toString());
310
		schemeModel.setAmountType(scheme.getAmountType().toString());
311
		schemeModel.setAmount(scheme.getAmount());
312
		schemeModel.setStartDateTime(StringUtils.toString(scheme.getStartDateTime()));
313
		schemeModel.setEndDateTime(StringUtils.toString(scheme.getEndDateTime()));
314
		schemeModel.setCreateTimestamp(StringUtils.toString(scheme.getCreateTimestamp()));
315
		schemeModel.setActiveTimestamp(StringUtils.toString(scheme.getActiveTimestamp()));
316
		schemeModel.setExpireTimestamp(StringUtils.toString(scheme.getExpireTimestamp()));
317
		schemeModel.setCreatedBy(scheme.getCreatedBy());
23339 ashik.ali 318
		schemeModel.setItemStringMap(scheme.getItemStringMap());
23019 ashik.ali 319
		schemeModel.setRetailerIds(scheme.getRetailerIds());
320
		return schemeModel;
321
	}
22653 ashik.ali 322
 
323
	@Override
324
	public void activeSchemeById(int schemeId) throws ProfitMandiBusinessException {
325
		Scheme scheme = schemeRepository.selectById(schemeId);
23444 amit.gupta 326
		if (scheme.getActiveTimestamp() != null) {
327
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ACTIVE_TIMESTAMP, scheme.getActiveTimestamp(),
328
					"SCHM_1005");
22653 ashik.ali 329
		}
23444 amit.gupta 330
		if (scheme.getExpireTimestamp() != null) {
331
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EXPIRE_TIMESTAMP, scheme.getExpireTimestamp(),
332
					"SCHM_1006");
22653 ashik.ali 333
		}
22859 ashik.ali 334
		scheme.setActiveTimestamp(LocalDateTime.now());
335
		schemeRepository.persist(scheme);
23444 amit.gupta 336
		if (scheme.getType() == SchemeType.IN) {
23019 ashik.ali 337
			this.processPreviousPurchases(scheme);
23444 amit.gupta 338
		} else if (scheme.getType() == SchemeType.OUT) {
23019 ashik.ali 339
			this.processPreviousSales(scheme);
340
		}
22653 ashik.ali 341
	}
23444 amit.gupta 342
 
343
	private void processPreviousPurchases(Scheme scheme) throws ProfitMandiBusinessException {
344
		List<InventoryItem> inventoryItems = inventoryItemRepository.selectBetweenDates(scheme.getStartDateTime(),
345
				scheme.getEndDateTime());
346
		if (inventoryItems.isEmpty()) {
23370 ashik.ali 347
			return;
348
		}
23019 ashik.ali 349
		List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(scheme.getId());
23444 amit.gupta 350
		if (itemIds.isEmpty()) {
23370 ashik.ali 351
			return;
352
		}
23339 ashik.ali 353
		List<Item> items = itemRepository.selectByIds(new HashSet<>(itemIds));
354
		Map<Integer, String> itemStringMap = this.toItemStringMap(items);
23444 amit.gupta 355
		List<InventoryItem> completedInventoryItems = this.toFilteredPurchaseCompletedInventoryItems(inventoryItems,
356
				itemIds, true);
357
		if (completedInventoryItems.isEmpty()) {
23370 ashik.ali 358
			return;
359
		}
23444 amit.gupta 360
		if (scheme.isRetailerAll()) {
361
			for (InventoryItem inventoryItem : completedInventoryItems) {
23019 ashik.ali 362
				float cashback = this.createSchemeInOut(scheme, inventoryItem);
23444 amit.gupta 363
				walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItem.getPurchaseId(),
364
						WalletReferenceType.SCHEME_IN,
23796 amit.gupta 365
						"Added SCHEME_IN for item " + itemStringMap.get(inventoryItem.getItemId())
366
								+ " against invoiceNumber " + inventoryItem.getPurchase().getPurchaseReference(),
23444 amit.gupta 367
						cashback);
23019 ashik.ali 368
			}
23444 amit.gupta 369
		} else {
23019 ashik.ali 370
			List<Integer> retailerIds = retailerSchemeRepository.selectRetailerIdsBySchemeId(scheme.getId());
23444 amit.gupta 371
			for (InventoryItem inventoryItem : completedInventoryItems) {
372
				if (retailerIds.contains(inventoryItem.getFofoId())) {
23019 ashik.ali 373
					float cashback = this.createSchemeInOut(scheme, inventoryItem);
23444 amit.gupta 374
					walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItem.getPurchaseId(),
375
							WalletReferenceType.SCHEME_IN,
23796 amit.gupta 376
							"Added SCHEME_IN for item " + itemStringMap.get(inventoryItem.getItemId())
377
									+ " against invoiceNumber " + inventoryItem.getPurchase().getPurchaseReference(),
378
							cashback);
23019 ashik.ali 379
				}
380
			}
381
		}
23444 amit.gupta 382
 
23019 ashik.ali 383
	}
23444 amit.gupta 384
 
385
	private Map<Integer, Integer> toInventoryItemIdFofoOrderIdMap(List<FofoLineItem> fofoLineItems,
386
			Map<Integer, FofoOrderItem> fofoOrderItemIdFofoOrderItemMap) {
23019 ashik.ali 387
		Map<Integer, Integer> inventoryItemIdFofoOrderIdMap = new HashMap<>();
23444 amit.gupta 388
 
389
		for (FofoLineItem fofoLineItem : fofoLineItems) {
390
			inventoryItemIdFofoOrderIdMap.put(fofoLineItem.getInventoryItemId(),
23019 ashik.ali 391
					fofoOrderItemIdFofoOrderItemMap.get(fofoLineItem.getFofoOrderItemId()).getOrderId());
392
		}
393
		return inventoryItemIdFofoOrderIdMap;
394
	}
23444 amit.gupta 395
 
396
	private void processPreviousSales(Scheme scheme) throws ProfitMandiBusinessException {
397
		List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectBetweenDates(scheme.getStartDateTime(),
398
				scheme.getEndDateTime());
399
 
400
		if (fofoOrderItems.isEmpty()) {
23370 ashik.ali 401
			return;
402
		}
22653 ashik.ali 403
 
23444 amit.gupta 404
		Map<Integer, FofoOrderItem> fofoOrderItemIdFofoOrderItemMap = this
405
				.toFofoOrderItemIdFofoOrderItemMap(fofoOrderItems);
406
 
407
		List<FofoLineItem> fofoLineItems = fofoLineItemRepository
408
				.selectByFofoOrderItemIds(fofoOrderItemIdFofoOrderItemMap.keySet());
409
 
410
		if (fofoLineItems.isEmpty()) {
23370 ashik.ali 411
			return;
412
		}
23444 amit.gupta 413
 
414
		Map<Integer, Integer> inventoryItemIdFofoOrderIdMap = this.toInventoryItemIdFofoOrderIdMap(fofoLineItems,
415
				fofoOrderItemIdFofoOrderItemMap);
416
 
417
		List<InventoryItem> inventoryItems = inventoryItemRepository
418
				.selectByIds(inventoryItemIdFofoOrderIdMap.keySet());
419
 
420
		if (inventoryItems.isEmpty()) {
23370 ashik.ali 421
			return;
422
		}
23444 amit.gupta 423
 
23019 ashik.ali 424
		List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(scheme.getId());
23444 amit.gupta 425
 
426
		if (itemIds.isEmpty()) {
23370 ashik.ali 427
			return;
428
		}
23444 amit.gupta 429
 
430
		List<InventoryItem> completedInventoryItems = this.toFilteredPurchaseCompletedInventoryItems(inventoryItems,
431
				itemIds, false);
432
 
433
		if (scheme.isRetailerAll()) {
434
			for (InventoryItem inventoryItem : completedInventoryItems) {
23019 ashik.ali 435
				float cashback = this.createSchemeInOut(scheme, inventoryItem);
23444 amit.gupta 436
				walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItem.getPurchaseId(),
437
						WalletReferenceType.SCHEME_OUT, "Added for SCHEME_OUT", cashback);
23019 ashik.ali 438
			}
23444 amit.gupta 439
		} else {
23019 ashik.ali 440
			List<Integer> retailerIds = retailerSchemeRepository.selectRetailerIdsBySchemeId(scheme.getId());
23444 amit.gupta 441
			for (InventoryItem inventoryItem : completedInventoryItems) {
442
				if (retailerIds.contains(inventoryItem.getFofoId())) {
23019 ashik.ali 443
					float cashback = this.createSchemeInOut(scheme, inventoryItem);
23444 amit.gupta 444
					walletService.addAmountToWallet(inventoryItem.getFofoId(),
445
							inventoryItemIdFofoOrderIdMap.get(inventoryItem.getId()), WalletReferenceType.SCHEME_OUT,
446
							"Added for SCHEME_OUT", cashback);
23019 ashik.ali 447
				}
448
			}
449
		}
450
	}
23444 amit.gupta 451
 
452
	private Map<Integer, FofoOrderItem> toFofoOrderItemIdFofoOrderItemMap(List<FofoOrderItem> fofoOrderItems) {
23019 ashik.ali 453
		Map<Integer, FofoOrderItem> fofoOrderItemIdFofoOrderItemMap = new HashMap<>();
23444 amit.gupta 454
		for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
23019 ashik.ali 455
			fofoOrderItemIdFofoOrderItemMap.put(fofoOrderItem.getId(), fofoOrderItem);
456
		}
457
		return fofoOrderItemIdFofoOrderItemMap;
458
	}
23444 amit.gupta 459
 
460
	private List<InventoryItem> toFilteredPurchaseCompletedInventoryItems(List<InventoryItem> inventoryItems,
461
			List<Integer> itemIds, boolean purchase) {
23019 ashik.ali 462
		List<InventoryItem> completedInventoryItems = new ArrayList<>();
23444 amit.gupta 463
		for (InventoryItem inventoryItem : inventoryItems) {
464
			if (purchase && inventoryItem.getPurchase().getCompleteTimestamp() != null
465
					&& itemIds.contains(inventoryItem.getItemId())) {
23019 ashik.ali 466
				completedInventoryItems.add(inventoryItem);
23444 amit.gupta 467
			} else if (!purchase && itemIds.contains(inventoryItem.getItemId())) {
23297 ashik.ali 468
				completedInventoryItems.add(inventoryItem);
23019 ashik.ali 469
			}
470
		}
471
		return completedInventoryItems;
472
	}
23444 amit.gupta 473
 
22653 ashik.ali 474
	@Override
475
	public void expireSchemeById(int schemeId) throws ProfitMandiBusinessException {
476
		Scheme scheme = schemeRepository.selectById(schemeId);
23444 amit.gupta 477
		if (scheme.getActiveTimestamp() == null) {
478
			throw new ProfitMandiBusinessException(ProfitMandiConstants.ACTIVE_TIMESTAMP, scheme.getActiveTimestamp(),
479
					"SCHM_1007");
22653 ashik.ali 480
		}
23444 amit.gupta 481
		if (scheme.getExpireTimestamp() != null) {
482
			throw new ProfitMandiBusinessException(ProfitMandiConstants.EXPIRE_TIMESTAMP, scheme.getExpireTimestamp(),
483
					"SCHM_1008");
22653 ashik.ali 484
		}
22859 ashik.ali 485
		scheme.setExpireTimestamp(LocalDateTime.now());
486
		schemeRepository.persist(scheme);
22653 ashik.ali 487
	}
23444 amit.gupta 488
 
489
	private Map<Integer, Scheme> toSchemeIdSchemeMap(List<Scheme> schemes) {
23019 ashik.ali 490
		Map<Integer, Scheme> schemeIdSchemeMap = new HashMap<>();
23444 amit.gupta 491
		for (Scheme scheme : schemes) {
23019 ashik.ali 492
			schemeIdSchemeMap.put(scheme.getId(), scheme);
22859 ashik.ali 493
		}
23019 ashik.ali 494
		return schemeIdSchemeMap;
22859 ashik.ali 495
	}
23444 amit.gupta 496
 
497
	private Set<Integer> inventoryItemSchemesMapToSchemeIds(Map<InventoryItem, Set<Scheme>> inventoryItemSchemesMap) {
22859 ashik.ali 498
		Set<Integer> schemeIds = new HashSet<>();
23444 amit.gupta 499
		for (Map.Entry<InventoryItem, Set<Scheme>> inventoryItemSchemesEntry : inventoryItemSchemesMap.entrySet()) {
500
			for (Scheme scheme : inventoryItemSchemesEntry.getValue()) {
22859 ashik.ali 501
				schemeIds.add(scheme.getId());
502
			}
503
		}
504
		return schemeIds;
505
	}
23444 amit.gupta 506
 
507
	private Set<Integer> fofoLineItemSchemesMapToSchemeIds(Map<FofoOrderItem, Set<Scheme>> fofoLineItemSchemesMap) {
22859 ashik.ali 508
		Set<Integer> schemeIds = new HashSet<>();
23444 amit.gupta 509
		for (Map.Entry<FofoOrderItem, Set<Scheme>> inventoryItemSchemesEntry : fofoLineItemSchemesMap.entrySet()) {
510
			for (Scheme scheme : inventoryItemSchemesEntry.getValue()) {
22859 ashik.ali 511
				schemeIds.add(scheme.getId());
512
			}
513
		}
514
		return schemeIds;
515
	}
23444 amit.gupta 516
 
517
	private Set<Integer> inventoryItemsToItemIds(List<InventoryItem> inventoryItems) {
22859 ashik.ali 518
		Set<Integer> itemIds = new HashSet<>();
23444 amit.gupta 519
		for (InventoryItem inventoryItem : inventoryItems) {
22859 ashik.ali 520
			itemIds.add(inventoryItem.getItemId());
521
		}
522
		return itemIds;
523
	}
23444 amit.gupta 524
 
525
	private Set<Integer> fofoOrderItemsToItemIds(List<FofoOrderItem> fofoOrderItems) {
22859 ashik.ali 526
		Set<Integer> itemIds = new HashSet<>();
23444 amit.gupta 527
		for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
22859 ashik.ali 528
			itemIds.add(fofoOrderItem.getItemId());
529
		}
530
		return itemIds;
531
	}
23444 amit.gupta 532
 
533
	private Map<Integer, Set<Scheme>> toItemIdSchemesMap(List<SchemeItem> schemeItems, List<Scheme> schemes) {
23019 ashik.ali 534
		Map<Integer, Scheme> schemeIdSchemesMap = this.toSchemeIdSchemeMap(schemes);
22859 ashik.ali 535
		Map<Integer, Set<Scheme>> itemIdSchemesMap = new HashMap<>();
23444 amit.gupta 536
		for (SchemeItem schemeItem : schemeItems) {
537
			if (!itemIdSchemesMap.containsKey(schemeItem.getItemId())) {
22859 ashik.ali 538
				Set<Scheme> schemesSet = new HashSet<>();
539
				schemesSet.add(schemeIdSchemesMap.get(schemeItem.getSchemeId()));
540
				itemIdSchemesMap.put(schemeItem.getItemId(), schemesSet);
23444 amit.gupta 541
			} else {
22859 ashik.ali 542
				itemIdSchemesMap.get(schemeItem.getItemId()).add(schemeIdSchemesMap.get(schemeItem.getSchemeId()));
543
			}
544
		}
545
		return itemIdSchemesMap;
546
	}
22653 ashik.ali 547
 
23444 amit.gupta 548
	private Map<InventoryItem, Set<Scheme>> toInventoryItemSchemesMap(List<Scheme> schemes,
549
			List<InventoryItem> inventoryItems) {
22859 ashik.ali 550
		Set<Integer> schemeIds = new HashSet<>();
23444 amit.gupta 551
		for (Scheme scheme : schemes) {
22859 ashik.ali 552
			schemeIds.add(scheme.getId());
553
		}
554
		Set<Integer> itemIds = this.inventoryItemsToItemIds(inventoryItems);
555
		List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIdsAndItemIds(schemeIds, itemIds);
23444 amit.gupta 556
 
22859 ashik.ali 557
		Map<Integer, Set<Scheme>> itemIdSchemesMap = this.toItemIdSchemesMap(schemeItems, schemes);
558
		Map<InventoryItem, Set<Scheme>> inventoryItemSchemsMap = new HashMap<>();
23444 amit.gupta 559
		for (InventoryItem inventoryItem : inventoryItems) {
560
			if (itemIdSchemesMap.containsKey(inventoryItem.getItemId())) {
22859 ashik.ali 561
				inventoryItemSchemsMap.put(inventoryItem, itemIdSchemesMap.get(inventoryItem.getItemId()));
562
			}
563
		}
564
		return inventoryItemSchemsMap;
565
	}
23444 amit.gupta 566
 
567
	private Map<FofoOrderItem, Set<Scheme>> toFofoOrderItemSchemesMap(List<Scheme> schemes,
568
			List<FofoOrderItem> fofoOrderItems) {
22859 ashik.ali 569
		Set<Integer> schemeIds = new HashSet<>();
23444 amit.gupta 570
		for (Scheme scheme : schemes) {
22859 ashik.ali 571
			schemeIds.add(scheme.getId());
572
		}
573
		Set<Integer> itemIds = this.fofoOrderItemsToItemIds(fofoOrderItems);
574
		List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIdsAndItemIds(schemeIds, itemIds);
23444 amit.gupta 575
 
22859 ashik.ali 576
		Map<FofoOrderItem, Set<Scheme>> fofoOrderItemSchemsMap = new HashMap<>();
23444 amit.gupta 577
 
578
		if (!schemeItems.isEmpty()) {
22859 ashik.ali 579
			Map<Integer, Set<Scheme>> itemIdSchemesMap = this.toItemIdSchemesMap(schemeItems, schemes);
23444 amit.gupta 580
			for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
581
				if (itemIdSchemesMap.containsKey(fofoOrderItem.getItemId())) {
22859 ashik.ali 582
					fofoOrderItemSchemsMap.put(fofoOrderItem, itemIdSchemesMap.get(fofoOrderItem.getItemId()));
583
				}
22653 ashik.ali 584
			}
585
		}
22859 ashik.ali 586
		return fofoOrderItemSchemsMap;
587
	}
23444 amit.gupta 588
 
22859 ashik.ali 589
	@Override
23365 ashik.ali 590
	public void processSchemeIn(int purchaseId, int retailerId) throws ProfitMandiBusinessException {
23369 ashik.ali 591
		LOGGER.info("Trying to process SchemeIn with purchaseId [{}] and retailerId [{}]", purchaseId, retailerId);
23344 ashik.ali 592
		Purchase purchase = purchaseRepository.selectByIdAndFofoId(purchaseId, retailerId);
23369 ashik.ali 593
		LOGGER.info("purchase is completed = {}", (purchase.getCompleteTimestamp() != null));
23444 amit.gupta 594
		if (purchase.getCompleteTimestamp() != null) {
595
			List<Order> orders = orderRepository.selectByAirwayBillOrInvoiceNumber(purchase.getPurchaseReference(),
596
					retailerId);
23378 ashik.ali 597
			LocalDateTime billingTimestamp = purchase.getCreateTimestamp();
23444 amit.gupta 598
			if (!orders.isEmpty()) {
23365 ashik.ali 599
				billingTimestamp = orders.get(0).getBillingTimestamp();
600
			}
601
			List<Scheme> schemes = schemeRepository.selectActiveAll(SchemeType.IN, billingTimestamp);
602
			float totalCashback = 0;
23444 amit.gupta 603
			if (schemes.isEmpty()) {
23365 ashik.ali 604
				return;
605
			}
606
			List<InventoryItem> inventoryItems = inventoryItemRepository.selectByPurchaseId(purchaseId);
23444 amit.gupta 607
 
608
			Map<InventoryItem, Set<Scheme>> inventoryItemSchemesMap = this.toInventoryItemSchemesMap(schemes,
609
					inventoryItems);
610
 
611
			if (inventoryItemSchemesMap.isEmpty()) {
23365 ashik.ali 612
				return;
613
			}
614
			Map<InventoryItem, Set<Scheme>> notAllInventoryItemSchemesMap = new HashMap<>();
615
			Map<InventoryItem, Set<Scheme>> allInventoryItemSchemesMap = new HashMap<>();
616
			Set<Integer> itemIds = new HashSet<>();
23444 amit.gupta 617
 
618
			for (Map.Entry<InventoryItem, Set<Scheme>> inventoryItemSchemesEntry : inventoryItemSchemesMap.entrySet()) {
23365 ashik.ali 619
				Set<Scheme> notAllSchemes = new HashSet<>();
620
				Set<Scheme> allSchemes = new HashSet<>();
23444 amit.gupta 621
				for (Scheme scheme : inventoryItemSchemesEntry.getValue()) {
622
					if (!scheme.isRetailerAll()) {
23365 ashik.ali 623
						notAllSchemes.add(scheme);
23444 amit.gupta 624
					} else {
23365 ashik.ali 625
						allSchemes.add(scheme);
626
					}
22859 ashik.ali 627
				}
23365 ashik.ali 628
				notAllInventoryItemSchemesMap.put(inventoryItemSchemesEntry.getKey(), notAllSchemes);
629
				allInventoryItemSchemesMap.put(inventoryItemSchemesEntry.getKey(), allSchemes);
630
				itemIds.add(inventoryItemSchemesEntry.getKey().getItemId());
22859 ashik.ali 631
			}
23444 amit.gupta 632
 
633
			int itemsCount = 0;
634
			for (Map.Entry<InventoryItem, Set<Scheme>> allInventoryItemSchemesEntry : allInventoryItemSchemesMap
635
					.entrySet()) {
636
				float inventoryItemCashback = 0;
637
				for (Scheme scheme : allInventoryItemSchemesEntry.getValue()) {
23365 ashik.ali 638
					InventoryItem inventoryItem = allInventoryItemSchemesEntry.getKey();
639
					float cashback = this.createSchemeInOut(scheme, inventoryItem);
23444 amit.gupta 640
					inventoryItemCashback += cashback;
23339 ashik.ali 641
				}
23444 amit.gupta 642
				if (inventoryItemCashback > 0) {
643
					totalCashback += inventoryItemCashback;
644
					itemsCount++;
645
				}
22859 ashik.ali 646
			}
23444 amit.gupta 647
 
23365 ashik.ali 648
			Set<Integer> schemeIds = this.inventoryItemSchemesMapToSchemeIds(notAllInventoryItemSchemesMap);
23444 amit.gupta 649
			if (!schemeIds.isEmpty()) {
23365 ashik.ali 650
				List<Integer> foundSchemeIds = retailerSchemeRepository.selectSchemeIds(schemeIds, retailerId);
23444 amit.gupta 651
				for (Map.Entry<InventoryItem, Set<Scheme>> notAllInventoryItemSchemesEntry : notAllInventoryItemSchemesMap
652
						.entrySet()) {
653
					float inventoryItemCashback = 0;
654
					for (Scheme scheme : notAllInventoryItemSchemesEntry.getValue()) {
655
						if (foundSchemeIds.contains(scheme.getId())) {
23365 ashik.ali 656
							InventoryItem inventoryItem = notAllInventoryItemSchemesEntry.getKey();
657
							float cashback = this.createSchemeInOut(scheme, inventoryItem);
23444 amit.gupta 658
							inventoryItemCashback += cashback;
23339 ashik.ali 659
						}
22653 ashik.ali 660
					}
23444 amit.gupta 661
					if (inventoryItemCashback > 0) {
662
						totalCashback += inventoryItemCashback;
663
						itemsCount++;
664
					}
22653 ashik.ali 665
				}
666
			}
23511 amit.gupta 667
			LOGGER.info("Items count for purchase id {} is {}", purchaseId, itemsCount);
23796 amit.gupta 668
			if (itemsCount > 0) {
23508 amit.gupta 669
				walletService.addAmountToWallet(retailerId, purchaseId, WalletReferenceType.SCHEME_IN,
23796 amit.gupta 670
						"Added for SCHEME IN against invoice " + purchase.getPurchaseReference() + " (total "
671
								+ itemsCount + " pcs)",
672
						totalCashback);
673
				LOGGER.info("Added Rs.{} for SCHEME IN against invoice {} total pcs({}) {}", totalCashback,
674
						purchase.getPurchaseReference(), itemsCount);
23508 amit.gupta 675
				purchase.setCashback(purchase.getCashback() + totalCashback);
676
				purchaseRepository.persist(purchase);
677
			}
22653 ashik.ali 678
		}
679
	}
23444 amit.gupta 680
 
681
	private float createSchemeInOut(Scheme scheme, InventoryItem inventoryItem) {
23443 amit.gupta 682
		SchemeInOut schemeInOut = schemeInOutRepository.selectByScheme(scheme.getId(), inventoryItem.getId());
683
		float amount = 0;
23444 amit.gupta 684
		if (schemeInOut == null) {
23443 amit.gupta 685
			schemeInOut = new SchemeInOut();
686
			amount = this.getAmount(inventoryItem, scheme);
687
			schemeInOut.setSchemeId(scheme.getId());
688
			schemeInOut.setInventoryItemId(inventoryItem.getId());
689
			schemeInOut.setAmount(amount);
690
			schemeInOutRepository.persist(schemeInOut);
691
		}
22859 ashik.ali 692
		return amount;
693
	}
23444 amit.gupta 694
 
695
	private float getAmount(InventoryItem inventoryItem, Scheme scheme) {
22653 ashik.ali 696
		float amount = 0;
22859 ashik.ali 697
		float totalTaxRate = inventoryItem.getIgstRate() + inventoryItem.getSgstRate() + inventoryItem.getCgstRate();
698
		float taxableSellingPrice = inventoryItem.getUnitPrice() / (1 + totalTaxRate / 100);
23444 amit.gupta 699
 
23527 ashik.ali 700
		if (scheme.getAmountType() == AmountType.PERCENTAGE) {
22859 ashik.ali 701
			amount = taxableSellingPrice * scheme.getAmount() / 100;
23444 amit.gupta 702
		} else {
22653 ashik.ali 703
			amount = scheme.getAmount();
704
		}
22859 ashik.ali 705
		return amount;
22653 ashik.ali 706
	}
23444 amit.gupta 707
 
708
	private Map<Integer, InventoryItem> toInventoryItemIdInventoryItemMap(List<InventoryItem> inventoryItems) {
22859 ashik.ali 709
		Map<Integer, InventoryItem> itemIdInventoryItemMap = new HashMap<>();
23444 amit.gupta 710
		for (InventoryItem inventoryItem : inventoryItems) {
22859 ashik.ali 711
			itemIdInventoryItemMap.put(inventoryItem.getId(), inventoryItem);
22653 ashik.ali 712
		}
22859 ashik.ali 713
		return itemIdInventoryItemMap;
22653 ashik.ali 714
	}
23444 amit.gupta 715
 
716
	private Set<Integer> toInventoryItemIds(Set<FofoOrderItem> fofoOrderItems) {
22859 ashik.ali 717
		Set<Integer> inventoryItemIds = new HashSet<>();
23444 amit.gupta 718
		// Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap =
719
		// this.toFofoOrderItemIdFofoLineItems(fofoOrderItems);
720
		for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
721
			for (FofoLineItem fofoLineItem : fofoOrderItem.getFofoLineItems()) {
22859 ashik.ali 722
				inventoryItemIds.add(fofoLineItem.getInventoryItemId());
723
			}
724
		}
725
		return inventoryItemIds;
726
	}
22653 ashik.ali 727
 
728
	@Override
23365 ashik.ali 729
	public void processSchemeOut(int fofoOrderId, int retailerId) throws ProfitMandiBusinessException {
730
		FofoOrder fofoOrder = fofoOrderRepository.selectByFofoIdAndOrderId(retailerId, fofoOrderId);
22859 ashik.ali 731
		List<Scheme> schemes = schemeRepository.selectActiveAll(SchemeType.OUT, LocalDateTime.now());
732
		LOGGER.info("Active Schemes {}", schemes);
733
		float totalCashback = 0;
23512 amit.gupta 734
		int count = 0;
23444 amit.gupta 735
		if (schemes.isEmpty()) {
23365 ashik.ali 736
			return;
22859 ashik.ali 737
		}
23444 amit.gupta 738
 
22925 ashik.ali 739
		List<FofoOrderItem> fofoOrderItems = orderService.getByOrderId(fofoOrderId);
23444 amit.gupta 740
		// LOGGER.info("fofoOrderItems {}", fofoOrderItems);
741
 
742
		Map<FofoOrderItem, Set<Scheme>> fofoOrderItemSchemesMap = this.toFofoOrderItemSchemesMap(schemes,
743
				fofoOrderItems);
744
 
22859 ashik.ali 745
		LOGGER.info("fofoOrderItemSchemesMap {}", fofoOrderItemSchemesMap);
23444 amit.gupta 746
 
747
		if (fofoOrderItemSchemesMap.isEmpty()) {
23365 ashik.ali 748
			return;
22859 ashik.ali 749
		}
23444 amit.gupta 750
 
22859 ashik.ali 751
		Set<Integer> inventoryItemIds = this.toInventoryItemIds(fofoOrderItemSchemesMap.keySet());
23444 amit.gupta 752
 
22859 ashik.ali 753
		List<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIds);
23444 amit.gupta 754
 
755
		Map<Integer, InventoryItem> inventoryItemIdInventoryItemMap = this
756
				.toInventoryItemIdInventoryItemMap(inventoryItems);
757
 
22859 ashik.ali 758
		Map<FofoOrderItem, Set<Scheme>> notAllFofoOrderItemSchemesMap = new HashMap<>();
759
		Map<FofoOrderItem, Set<Scheme>> allFofoOrderItemSchemesMap = new HashMap<>();
23444 amit.gupta 760
 
761
		for (Map.Entry<FofoOrderItem, Set<Scheme>> fofoOrderItemSchemesEntry : fofoOrderItemSchemesMap.entrySet()) {
22859 ashik.ali 762
			Set<Scheme> notAllSchemes = new HashSet<>();
763
			Set<Scheme> allSchemes = new HashSet<>();
23444 amit.gupta 764
			for (Scheme scheme : fofoOrderItemSchemesEntry.getValue()) {
765
				if (!scheme.isRetailerAll()) {
22859 ashik.ali 766
					notAllSchemes.add(scheme);
23444 amit.gupta 767
				} else {
22859 ashik.ali 768
					allSchemes.add(scheme);
769
				}
22653 ashik.ali 770
			}
22859 ashik.ali 771
			notAllFofoOrderItemSchemesMap.put(fofoOrderItemSchemesEntry.getKey(), notAllSchemes);
772
			allFofoOrderItemSchemesMap.put(fofoOrderItemSchemesEntry.getKey(), allSchemes);
22653 ashik.ali 773
		}
23444 amit.gupta 774
 
775
		for (Map.Entry<FofoOrderItem, Set<Scheme>> allFofoOrderItemSchemesEntry : allFofoOrderItemSchemesMap
776
				.entrySet()) {
777
			for (FofoLineItem fofoLineItem : allFofoOrderItemSchemesEntry.getKey().getFofoLineItems()) {
23796 amit.gupta 778
				float itemCashback = 0;
23444 amit.gupta 779
				for (Scheme scheme : allFofoOrderItemSchemesEntry.getValue()) {
23796 amit.gupta 780
					itemCashback += this.createSchemeInOut(scheme,
23444 amit.gupta 781
							inventoryItemIdInventoryItemMap.get(fofoLineItem.getInventoryItemId()));
22859 ashik.ali 782
				}
23796 amit.gupta 783
				if (itemCashback > 0) {
784
					totalCashback += itemCashback;
785
					count += 1;
786
				}
22859 ashik.ali 787
			}
22653 ashik.ali 788
		}
23444 amit.gupta 789
 
22859 ashik.ali 790
		Set<Integer> schemeIds = this.fofoLineItemSchemesMapToSchemeIds(notAllFofoOrderItemSchemesMap);
23444 amit.gupta 791
 
792
		if (!schemeIds.isEmpty()) {
22859 ashik.ali 793
			List<Integer> foundSchemeIds = retailerSchemeRepository.selectSchemeIds(schemeIds, retailerId);
23444 amit.gupta 794
 
795
			for (Map.Entry<FofoOrderItem, Set<Scheme>> notAllFofoOrderItemSchemesEntry : notAllFofoOrderItemSchemesMap
796
					.entrySet()) {
797
				for (FofoLineItem fofoLineItem : notAllFofoOrderItemSchemesEntry.getKey().getFofoLineItems()) {
23796 amit.gupta 798
					float itemCashback = 0;
23444 amit.gupta 799
					for (Scheme scheme : notAllFofoOrderItemSchemesEntry.getValue()) {
800
						if (foundSchemeIds.contains(scheme.getId())) {
23796 amit.gupta 801
							itemCashback += this.createSchemeInOut(scheme,
23444 amit.gupta 802
									inventoryItemIdInventoryItemMap.get(fofoLineItem.getInventoryItemId()));
22653 ashik.ali 803
						}
804
					}
23796 amit.gupta 805
					if (itemCashback > 0) {
806
						totalCashback += itemCashback;
807
						count += 1;
808
					}
22653 ashik.ali 809
				}
23444 amit.gupta 810
			}
22653 ashik.ali 811
		}
23444 amit.gupta 812
		if (totalCashback > 0) {
813
			walletService.addAmountToWallet(retailerId, fofoOrderId, WalletReferenceType.SCHEME_OUT,
23796 amit.gupta 814
					"Sales margin for invoice number " + fofoOrder.getInvoiceNumber() + ". Total " + count + " pc(s)",
815
					totalCashback);
23365 ashik.ali 816
			fofoOrder.setCashback(totalCashback);
817
			fofoOrderRepository.persist(fofoOrder);
22859 ashik.ali 818
		}
22653 ashik.ali 819
	}
23444 amit.gupta 820
 
23508 amit.gupta 821
	@Override
23796 amit.gupta 822
	public void rollbackSchemes(List<Integer> inventoryItemIds, int rollbackReference, String rollbackReason)
823
			throws Exception {
23638 amit.gupta 824
		Set<Integer> inventoryItemIdSet = new HashSet<>(inventoryItemIds);
23508 amit.gupta 825
		float amountToRollback = 0;
826
		List<SchemeInOut> schemes = schemeInOutRepository.selectByInventoryItemIds(inventoryItemIdSet);
23796 amit.gupta 827
		for (SchemeInOut schemeInOut : schemes) {
23527 ashik.ali 828
			schemeInOut.setRolledBackTimestamp(LocalDateTime.now());
23508 amit.gupta 829
			schemeInOutRepository.persist(schemeInOut);
830
			amountToRollback += schemeInOut.getAmount();
831
		}
23796 amit.gupta 832
		if (schemes.size() > 0) {
23638 amit.gupta 833
			int inventoryItemId = inventoryItemIds.get(0);
834
			Integer fofoId = inventoryItemRepository.selectById(inventoryItemId).getFofoId();
23796 amit.gupta 835
			walletService.rollbackAmountFromWallet(fofoId, amountToRollback, rollbackReference,
836
					WalletReferenceType.SCHEME_IN, rollbackReason);
23638 amit.gupta 837
		}
23508 amit.gupta 838
	}
23796 amit.gupta 839
 
23781 ashik.ali 840
	@Override
23796 amit.gupta 841
	public Map<String, Object> getSchemes(Set<Integer> roleIds, int offset, int limit)
842
			throws ProfitMandiBusinessException {
23781 ashik.ali 843
		Map<String, Object> map = new HashMap<>();
844
		List<Scheme> schemes = null;
845
		long size = 0;
23798 amit.gupta 846
		if (roleManager.isAdmin(roleIds)) {
23781 ashik.ali 847
			schemes = schemeRepository.selectAll(offset, limit);
848
			size = schemeRepository.selectAllCount();
23796 amit.gupta 849
		} else {
23781 ashik.ali 850
			schemes = schemeRepository.selectActiveAll(offset, limit);
851
			size = schemeRepository.selectAllActiveCount();
852
		}
853
		map.put("schemes", schemes);
854
		map.put("start", offset + 1);
855
		map.put("size", size);
23796 amit.gupta 856
		if (schemes.size() < limit) {
23781 ashik.ali 857
			map.put("end", offset + schemes.size());
23796 amit.gupta 858
		} else {
23781 ashik.ali 859
			map.put("end", offset + limit);
860
		}
861
		return map;
862
	}
23796 amit.gupta 863
 
23781 ashik.ali 864
	@Override
23796 amit.gupta 865
	public List<Scheme> getPaginatedSchemes(Set<Integer> roleIds, int offset, int limit)
866
			throws ProfitMandiBusinessException {
23781 ashik.ali 867
		LOGGER.info("requested offset=[{}], limit = [{}]", offset, limit);
868
		List<Scheme> schemes = null;
23798 amit.gupta 869
		if (roleManager.isAdmin(roleIds)) {
23781 ashik.ali 870
			schemes = schemeRepository.selectAll(offset, limit);
23796 amit.gupta 871
		} else {
23781 ashik.ali 872
			schemes = schemeRepository.selectActiveAll(offset, limit);
873
		}
874
		return schemes;
875
	}
23508 amit.gupta 876
 
22653 ashik.ali 877
}