Subversion Repositories SmartDukaan

Rev

Rev 24785 | Rev 24826 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 24785 Rev 24810
Line 1... Line 1...
1
package com.smartdukaan.cron.scheduled;
1
package com.smartdukaan.cron.scheduled;
2
 
2
 
3
import java.text.Normalizer.Form;
3
import java.io.Serializable;
4
import java.time.LocalDate;
4
import java.time.LocalDate;
5
import java.util.ArrayList;
5
import java.util.ArrayList;
6
import java.util.Arrays;
6
import java.util.Arrays;
-
 
7
import java.util.HashSet;
7
import java.util.List;
8
import java.util.List;
8
import java.util.Map;
9
import java.util.Map;
9
import java.util.logging.SimpleFormatter;
10
import java.util.Set;
10
import java.util.stream.Collectors;
11
import java.util.stream.Collectors;
11
 
12
 
12
import org.apache.commons.io.output.ByteArrayOutputStream;
13
import org.apache.commons.io.output.ByteArrayOutputStream;
13
import org.springframework.beans.factory.annotation.Autowired;
14
import org.springframework.beans.factory.annotation.Autowired;
14
import org.springframework.core.io.ByteArrayResource;
15
import org.springframework.core.io.ByteArrayResource;
Line 16... Line 17...
16
import org.springframework.stereotype.Component;
17
import org.springframework.stereotype.Component;
17
 
18
 
18
import com.spice.profitmandi.common.util.FileUtil;
19
import com.spice.profitmandi.common.util.FileUtil;
19
import com.spice.profitmandi.common.util.FormattingUtils;
20
import com.spice.profitmandi.common.util.FormattingUtils;
20
import com.spice.profitmandi.common.util.Utils;
21
import com.spice.profitmandi.common.util.Utils;
-
 
22
import com.spice.profitmandi.dao.entity.catalog.Scheme;
-
 
23
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
-
 
24
import com.spice.profitmandi.dao.entity.fofo.SchemeInOut;
21
import com.spice.profitmandi.dao.entity.transaction.Order;
25
import com.spice.profitmandi.dao.entity.transaction.Order;
22
import com.spice.profitmandi.dao.entity.transaction.ReturnOrder;
26
import com.spice.profitmandi.dao.entity.transaction.ReturnOrder;
23
import com.spice.profitmandi.dao.entity.transaction.UserWallet;
27
import com.spice.profitmandi.dao.entity.transaction.UserWallet;
24
import com.spice.profitmandi.dao.entity.transaction.UserWalletHistory;
28
import com.spice.profitmandi.dao.entity.transaction.UserWalletHistory;
-
 
29
import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;
-
 
30
import com.spice.profitmandi.dao.repository.catalog.SchemeRepository;
25
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
31
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
-
 
32
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
-
 
33
import com.spice.profitmandi.dao.repository.fofo.SchemeInOutRepository;
26
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
34
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
27
import com.spice.profitmandi.dao.repository.transaction.ReturnOrderRepository;
35
import com.spice.profitmandi.dao.repository.transaction.ReturnOrderRepository;
28
import com.spice.profitmandi.dao.repository.transaction.UserWalletHistoryRepository;
36
import com.spice.profitmandi.dao.repository.transaction.UserWalletHistoryRepository;
29
import com.spice.profitmandi.dao.repository.transaction.UserWalletRepository;
37
import com.spice.profitmandi.dao.repository.transaction.UserWalletRepository;
30
import com.spice.profitmandi.service.user.RetailerService;
38
import com.spice.profitmandi.service.user.RetailerService;
Line 39... Line 47...
39
	@Autowired
47
	@Autowired
40
	private UserWalletRepository userWalletRepository;
48
	private UserWalletRepository userWalletRepository;
41
	@Autowired
49
	@Autowired
42
	private UserWalletHistoryRepository userWalletHistoryRepository;
50
	private UserWalletHistoryRepository userWalletHistoryRepository;
43
	@Autowired
51
	@Autowired
-
 
52
	private SchemeInOutRepository schemeInOutRepository;
-
 
53
	@Autowired
-
 
54
	private SchemeRepository schemeRepository;
-
 
55
	@Autowired
-
 
56
	private InventoryItemRepository inventoryRepository;
-
 
57
	@Autowired
44
	private RetailerService retailerService;
58
	private RetailerService retailerService;
45
	@Autowired
59
	@Autowired
46
	private ReturnOrderRepository returnOrderRepository;
60
	private ReturnOrderRepository returnOrderRepository;
47
	@Autowired
61
	@Autowired
48
	private OrderRepository orderRepository;
62
	private OrderRepository orderRepository;
49
	@Autowired
63
	@Autowired
50
	private JavaMailSender mailSender;
64
	private JavaMailSender mailSender;
51
 
65
 
52
	public void dailyReconciliation() throws Exception {
66
	public void dailyReconciliation() throws Exception {
-
 
67
		Map<SchemeType, Set<Integer>> schemeTypeMap = schemeRepository.selectAll().stream()
-
 
68
				.collect(Collectors.groupingBy(Scheme::getType, Collectors.mapping(Scheme::getId, Collectors.toSet())));
53
		boolean reconciled = true;
69
		boolean reconciled = true;
54
		Map<Integer, String> stores = fofoStoreRepository.getStoresMap();
70
		Map<Integer, String> stores = fofoStoreRepository.getStoresMap();
55
		List<List<?>> rows = new ArrayList<>();
71
		List<List<? extends Serializable>> rows = new ArrayList<>();
56
		LocalDate yesterday = LocalDate.now().minusDays(1);
72
		LocalDate yesterday = LocalDate.now().minusDays(1);
57
		Map<Integer, String> retailerNameMap = retailerService
73
		Map<Integer, String> retailerNameMap = retailerService
58
				.getAllFofoRetailerIdNameMap(new ArrayList<>(stores.keySet()));
74
				.getAllFofoRetailerIdNameMap(new ArrayList<>(stores.keySet()));
59
		for (int partnerId : stores.keySet()) {
75
		for (int partnerId : stores.keySet()) {
60
			UserWallet uw = userWalletRepository.selectByRetailerId(partnerId);
76
			UserWallet uw = userWalletRepository.selectByRetailerId(partnerId);
61
			List<UserWalletHistory> walletHistory = userWalletHistoryRepository.selectByWalletIdAndDate(uw.getId(),
77
			List<UserWalletHistory> walletHistory = userWalletHistoryRepository.selectByWalletIdAndDate(uw.getId(),
62
					yesterday);
78
					yesterday);
63
			Map<LocalDate, List<UserWalletHistory>> dateWiseWalletHistory = walletHistory.stream()
79
			Map<WalletReferenceType, List<UserWalletHistory>> referenceWiseWalletHistory = walletHistory.stream()
64
					.collect(Collectors.groupingBy(x -> x.getTimestamp().toLocalDate(), Collectors.toList()));
80
					.collect(Collectors.groupingBy(x -> x.getReferenceType(), Collectors.toList()));
-
 
81
 
65
			for (Map.Entry<LocalDate, List<UserWalletHistory>> entry : dateWiseWalletHistory.entrySet()) {
82
			for (Map.Entry<WalletReferenceType, List<UserWalletHistory>> entry : referenceWiseWalletHistory
-
 
83
					.entrySet()) {
66
				LocalDate dateToReconcile = entry.getKey();
84
				LocalDate dateToReconcile = yesterday;
67
				List<UserWalletHistory> history = entry.getValue();
85
				List<UserWalletHistory> history = entry.getValue();
-
 
86
				List<Serializable> reconciliation = Arrays.asList(retailerNameMap.get(partnerId));
-
 
87
				Map<Integer, Integer> referenceWalletMap = entry.getValue().stream().collect(
-
 
88
						Collectors.groupingBy(x -> x.getReference(), Collectors.summingInt(x -> x.getAmount())));
-
 
89
				switch (entry.getKey()) {
-
 
90
				case PURCHASE:
-
 
91
					reconciliation.addAll(
68
				List<?> reconciliation = reconcileOrdersAndWallet(uw.getUserId(), retailerNameMap.get(partnerId), dateToReconcile,history);
92
							reconcileOrdersAndWallet(uw.getUserId(), dateToReconcile, referenceWalletMap, history));
-
 
93
					break;
-
 
94
				case SCHEME_IN:
-
 
95
					reconciliation.addAll(reconcileSchemeInAndWallet(uw.getUserId(), dateToReconcile,
-
 
96
							referenceWalletMap, history, schemeTypeMap.get(SchemeType.IN)));
-
 
97
					break;
-
 
98
				case SCHEME_OUT:
-
 
99
					break;
-
 
100
				default:
-
 
101
					break;
-
 
102
 
-
 
103
				}
69
				reconciled = reconciled || Boolean.TRUE.equals(reconciliation.remove(0));
104
				reconciled = reconciled || Boolean.TRUE.equals(reconciliation.get(0));
70
				rows.add(reconciliation);
105
				rows.add(reconciliation);
71
			}
106
			}
72
		}
107
		}
73
		ByteArrayOutputStream baos = FileUtil.getCSVByteStream(Arrays.asList("Store Code", "Date",
108
		ByteArrayOutputStream baos = FileUtil.getCSVByteStream(Arrays.asList("Store Name", "Wallet amount consumed",
-
 
109
				"Ordered Total", "Cancelled Total", "Refunded Total", "Scheme In to Wallet", "Scheme In disbursed", "Scheme In rolledback",
74
				"Wallet amount consumed", "Ordered Total", "Cancelled Total", "Refunded Total"), rows);
110
				"Scheme Out to Wallet", "Scheme Out Disbursed", "Scheme Out Rolledback"), rows);
75
 
111
 
76
		Utils.sendMailWithAttachment(mailSender, new String[] { "amit.gupta@shop2020.in" }, new String[] {}, 
112
		Utils.sendMailWithAttachment(mailSender, new String[] { "amit.gupta@shop2020.in" }, new String[] {},
77
				reconciled ? "Reconciled Successfully": "Reconciliation failed",
113
				reconciled ? "Reconciled Successfully" : "Reconciliation failed", "Report attached",
78
				"Report attached", String.format("reconciliation-%s.csv", FormattingUtils.formatDate(yesterday.atStartOfDay())), new ByteArrayResource(baos.toByteArray()));
114
				String.format("reconciliation-%s.csv", FormattingUtils.formatDate(yesterday.atStartOfDay())),
-
 
115
				new ByteArrayResource(baos.toByteArray()));
79
	}
116
	}
80
 
117
 
81
	private List<?> reconcileOrdersAndWallet(int fofoId, String storeName, LocalDate localDate, List<UserWalletHistory> history)
118
	private List<? extends Serializable> reconcileOrdersAndWallet(int fofoId, LocalDate localDate,
82
			throws Exception {
-
 
83
		Map<Integer, Integer> transactionsOnThatDate = history.stream()
119
			Map<Integer, Integer> transactionsOnThatDate, List<UserWalletHistory> history) throws Exception {
84
				.filter(x -> x.getReferenceType().equals(WalletReferenceType.PURCHASE))
-
 
85
				.collect(Collectors.groupingBy(x -> x.getReference(), Collectors.summingInt(x -> x.getAmount())));
-
 
86
 
120
 
87
		int totalWalletConsumed = 0;
121
		int totalWalletConsumed = 0;
88
		float cancelledAmount = 0;
122
		float cancelledAmount = 0;
89
		float returnedAmount = 0;
123
		float returnedAmount = 0;
90
		float totalDeductedAmount = 0;
124
		float totalDeductedAmount = 0;
Line 114... Line 148...
114
						returnedAmount += returnedOrder.getTotalPrice();
148
						returnedAmount += returnedOrder.getTotalPrice();
115
					}
149
					}
116
				}
150
				}
117
			}
151
			}
118
			totalWalletConsumed -= transactionsOnThatDate.get(transactionId);
152
			totalWalletConsumed -= transactionsOnThatDate.get(transactionId);
119
			
153
 
120
		}
154
		}
-
 
155
		boolean reconciled = Math
121
		boolean reconciled = Math.abs(totalWalletConsumed - (totalDeductedAmount-cancelledAmount - returnedAmount) ) < 2;
156
				.abs(totalWalletConsumed - (totalDeductedAmount - cancelledAmount - returnedAmount)) < 2;
122
 
157
 
123
		return Arrays.asList(reconciled, localDate, storeName, totalWalletConsumed, totalDeductedAmount, cancelledAmount, returnedAmount);
158
		return Arrays.asList(reconciled, totalWalletConsumed, totalDeductedAmount, cancelledAmount, returnedAmount);
124
 
159
 
125
	}
160
	}
126
 
161
 
-
 
162
	private List<? extends Serializable> reconcileSchemeInAndWallet(int fofoId, LocalDate localDate,
-
 
163
			Map<Integer, Integer> transactionsOnThatDate, List<UserWalletHistory> history, Set<Integer> schemeIds) {
-
 
164
 
127
	private void reconcileDailySchemeIn() {
165
		int totalSchemeInWalletCredited = 0;
-
 
166
		float schemeInAmountAdded = 0;
-
 
167
		float schemeInAmountRolledBack = 0;
-
 
168
		for (int transactionId : transactionsOnThatDate.keySet()) {
-
 
169
			List<InventoryItem> inventoryItems = inventoryRepository.selectByPurchaseId(transactionId).stream()
-
 
170
					.filter(x -> x.getSerialNumber() != null).collect(Collectors.toList());
-
 
171
			Set<Integer> inventoryItemIds = inventoryItems.stream().map(x -> x.getId()).collect(Collectors.toSet());
-
 
172
			List<SchemeInOut> sios = schemeInOutRepository.selectByInventoryItemIds(new HashSet<>(inventoryItemIds))
-
 
173
					.stream().filter(x -> schemeIds.contains(x.getSchemeId())).collect(Collectors.toList());
-
 
174
			totalSchemeInWalletCredited += transactionsOnThatDate.get(transactionId);
-
 
175
			for (SchemeInOut sio : sios) {
-
 
176
				if (sio.getCreateTimestamp().toLocalDate().equals(localDate)) {
-
 
177
					schemeInAmountAdded += sio.getAmount();
-
 
178
				}
-
 
179
				if (sio.getRolledBackTimestamp().toLocalDate().equals(localDate)) {
-
 
180
					schemeInAmountAdded += sio.getAmount();
-
 
181
				}
-
 
182
			}
-
 
183
 
-
 
184
		}
-
 
185
		boolean reconciled = Math.abs(totalSchemeInWalletCredited - (schemeInAmountAdded - schemeInAmountRolledBack)) < 5;
-
 
186
 
-
 
187
		return Arrays.asList(reconciled, totalSchemeInWalletCredited, schemeInAmountAdded, schemeInAmountRolledBack);
128
 
188
 
129
	}
189
	}
130
 
190
 
131
	private void reconcileDailySchemeOut() {
191
	private void reconcileSchemeOutAndWallet() {
132
 
192
 
133
	}
193
	}
134
}
194
}