Subversion Repositories SmartDukaan

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
21410 amit.gupta 1
package com.spice.profitmandi.web.controller.checkout;
2
 
3
import java.util.HashMap;
4
import java.util.Map;
5
 
6
import org.apache.thrift.TException;
7
import org.apache.thrift.transport.TTransportException;
8
import org.slf4j.Logger;
9
import org.slf4j.LoggerFactory;
10
 
11
import com.spice.profitmandi.thrift.clients.PaymentClient;
12
import com.spice.profitmandi.thrift.clients.PromotionClient;
13
import com.spice.profitmandi.thrift.clients.TransactionClient;
14
import com.spice.profitmandi.thrift.clients.UserClient;
15
 
16
import in.shop2020.logistics.PickUpType;
17
import in.shop2020.model.v1.order.LineItem;
18
import in.shop2020.model.v1.order.Order;
19
import in.shop2020.model.v1.order.OrderSource;
20
import in.shop2020.model.v1.order.OrderType;
21
import in.shop2020.model.v1.order.RechargeOrder;
22
import in.shop2020.model.v1.order.Transaction;
23
import in.shop2020.model.v1.order.TransactionService.Client;
24
import in.shop2020.model.v1.order.TransactionServiceException;
25
import in.shop2020.model.v1.order.TransactionStatus;
26
import in.shop2020.model.v1.user.PromotionException;
27
import in.shop2020.model.v1.user.ShoppingCartException;
28
import in.shop2020.payments.Payment;
29
import in.shop2020.payments.PaymentException;
30
 
31
/**
32
 * This class has methods to be used to process non-gateway-specific aspects of
33
 * payments and transactions.
34
 * 
35
 * @author Chandranshu
36
 * 
37
 */
38
public class CommonPaymentService {
39
 
40
	private static final boolean PAYMENT_NOT_CREATED = false;
41
 
42
	private static final Logger log=LoggerFactory.getLogger(CommonPaymentService.class);
43
 
44
	private long paymentId;
45
	private double amount;
46
 
47
	public long getPaymentId() {
48
		return paymentId;
49
	}
50
 
51
	public double getAmount() {
52
		return amount;
53
	}
54
 
55
	/**
56
	 * Creates a payment for the given cart of the given user for the given
57
	 * transaction. Stores the id of the newly created payment and the amount
58
	 * for which this payment was created. They can be retrieved later on using
59
	 * {@link #getPaymentId()}getPaymentId() and {@link #getAmount()}getAmount()
60
	 * methods respectively later on.
61
	 * 
62
	 * @param userId
63
	 *            The user for whom the payment has to be created.
64
	 * @param txnId
65
	 *            The transaction against which the payment has to be created.
66
	 * @param gatewayId
67
	 * @return True if the payment object is successfully created, False
68
	 *         otherwise.
69
	 */
70
	public boolean createPayment(long userId, long txnId, int gatewayId){
71
		TransactionClient transactionClient = null;
72
		Client tc = null;
73
		try {
74
			transactionClient = new TransactionClient();
75
			tc = transactionClient.getClient();
76
		} catch (TTransportException e) {
77
			log.error("Unable to create transaction client",e);
78
			return PAYMENT_NOT_CREATED;
79
		}
80
 
81
		try {
82
			amount = calculatePaymentAmount(txnId);
83
		} catch (Exception e1) {
84
			log.error("Unable to calcuate payment amount",e1);
85
			return PAYMENT_NOT_CREATED;
86
		}
87
 
88
		try {
89
			paymentId = tc.createPayment(userId, txnId, gatewayId);
90
		} catch (TException e) {
91
			log.error("Unable to create payment",e);
92
			return PAYMENT_NOT_CREATED;
93
		}
94
 
95
		return true;
96
	}
97
 
98
	// TODO: The service client parameters in the processSuccessfulTxn et al are
99
	// unnecessary but initializing them again when the caller has the necessary
100
	// references has a performance overhead. Need to think more about this.
101
 
102
	/**
103
	 * Processes a successful transaction by:
104
	 * <ol>
105
	 * <li>Marking the given transaction as 'authorized'.</li>
106
	 * <li>Removing the items in the cart for which the given transaction was
107
	 * processed.</li>
108
	 * <li>Marking the coupon associated with this transaction, if any, as used
109
	 * for this user.</li>
110
	 * <li>Queuing the transaction successful email, containing transaction
111
	 * info, to be sent later by a batch job.</li>
112
	 * </ol>
113
	 * <br>
114
	 * Please note that it's possible that a user has added items to the cart
115
	 * and so it's not possible to simply wipe out their cart. Therefore, it's
116
	 * important to ensure that we remove only as much quantity of items as for
117
	 * which the order was processed.
118
	 * 
119
	 * @param txnId
120
	 *            The transaction which should be marked as successful.
121
	 * @param userServiceClient
122
	 *            A user context service client to use.
123
	 * @param transactionServiceClient
124
	 *            A transaction service client to use.
125
	 * @param isFlagged
126
	 * 			  If payment is flagged it will be true else false 
127
	 */
128
	public static void processSuccessfulTxn(long txnId, UserClient userServiceClient, TransactionClient transactionServiceClient, boolean isFlagged) {
129
		Transaction transaction = null;
130
		TransactionStatus tStatus = TransactionStatus.AUTHORIZED;
131
		String description = "Payment authorized for the order";
132
		// if flag is set, status to be changed to flagged
133
		if(isFlagged){
134
			tStatus = TransactionStatus.FLAGGED;
135
			description = "Payment flagged for the order";
136
		}
137
		try {
138
			in.shop2020.model.v1.order.TransactionService.Client transactionClient = transactionServiceClient.getClient();
139
			transaction = transactionClient.getTransaction(txnId);
140
			transactionClient.changeTransactionStatus(txnId, tStatus, description, PickUpType.COURIER.getValue(), null, null);
141
			transactionClient.enqueueTransactionInfoEmail(txnId);
142
		} catch (TException e1) {
143
			log.error("Unable to update status of transaction. Thrift Exception:", e1);
144
		} catch (TransactionServiceException e) {
145
			log.error("Unable to update status of transaction. Thrift Exception: ", e);
146
		}
147
		long sum = resetCart(transaction, userServiceClient);
148
		trackCouponUsage(transaction, sum);
149
	}
150
 
151
	/**
152
	 * Marks a transaction as well as all its orders as failed.
153
	 * 
154
	 * @param txnId
155
	 *            The id of the transaction which has to be marked as failed.
156
	 * @param transactionServiceClient
157
	 */
158
	public static void processFailedTxn(long txnId, TransactionClient transactionServiceClient) {
159
		try {
160
			in.shop2020.model.v1.order.TransactionService.Client transactionClient = transactionServiceClient.getClient();
161
			transactionClient.changeTransactionStatus(txnId, TransactionStatus.FAILED, "Payment failed for the transaction.", PickUpType.COURIER.getValue(), OrderType.B2C, OrderSource.WEBSITE);
162
		} catch(TException e){
163
			log.error("Thrift exception while getting information from transaction service.", e);
164
		} catch (TransactionServiceException e) {
165
			log.error("Error while updating status information in transaction database.", e);
166
		}
167
	}
168
 
169
	/**
170
	 * Processes a COD transaction by:
171
	 * <ol>
172
	 * <li>Setting the COD flag of all the orders and moving them to the INIT
173
	 * state.
174
	 * <li>Marking the given transaction to be in COD_IN_PROCESS state
175
	 * <li>Marking the coupon associated with this transaction, if any, as used
176
	 * for this user.</li>
177
	 * <li>Queuing the transaction successful email, containing transaction
178
	 * info, to be sent later by a batch job.</li>
179
	 * </ol>
180
	 * <br>
181
	 * Please note that it's possible that a user has added items to the cart
182
	 * and so it's not possible to simply wipe out their cart. Therefore, it's
183
	 * important to ensure that we remove only as much quantity of items as for
184
	 * which the order was processed.
185
	 * 
186
	 * @param txnId
187
	 *            The COD transaction which should be marked as verification
188
	 *            pending.
189
	 */
190
	public static void processCodTxn(long txnId, OrderType orderType){
191
		try {            
192
			TransactionClient transactionServiceClient = new TransactionClient();
193
			in.shop2020.model.v1.order.TransactionService.Client transactionClient = transactionServiceClient.getClient();
194
			transactionClient.changeTransactionStatus(txnId, TransactionStatus.COD_IN_PROCESS, "COD payment awaited", PickUpType.COURIER.getValue(), orderType, OrderSource.WEBSITE);
195
			Transaction transaction = transactionClient.getTransaction(txnId);
196
			transactionClient.enqueueTransactionInfoEmail(txnId);
197
 
198
			UserClient userServiceClient = new UserClient();
199
			long sum = resetCart(transaction, userServiceClient);
200
			trackCouponUsage(transaction, sum);
201
		} catch (TException e1) {
202
			log.error("Unable to update status of transaction. Thrift Exception:", e1);
203
		} catch (TransactionServiceException e) {
204
			log.error("Unable to update status of transaction. Thrift Exception: ", e);
205
		} catch (Exception e) {
206
			log.error("Unable to update status of transaction. Thrift Exception: ", e);
207
		}
21469 amit.gupta 208
		log.info("successfully processed cod transaction");
21410 amit.gupta 209
	}
210
 
211
	public static void processCouponTxn(long txnId, OrderType orderType){
212
		try {            
213
			TransactionClient transactionServiceClient = new TransactionClient();
214
			in.shop2020.model.v1.order.TransactionService.Client transactionClient = transactionServiceClient.getClient();
215
			transactionClient.changeTransactionStatus(txnId, TransactionStatus.AUTHORIZED, "Payment by coupon successful", PickUpType.COURIER.getValue(), orderType, OrderSource.WEBSITE);
216
			Transaction transaction = transactionClient.getTransaction(txnId);
217
			UserClient userServiceClient = new UserClient();
218
			long sum = resetCart(transaction, userServiceClient);
219
			trackCouponUsage(transaction, sum);
220
		} catch (TException e1) {
221
			log.error("Unable to update status of transaction. Thrift Exception:", e1);
222
		} catch (TransactionServiceException e) {
223
			log.error("Unable to update status of transaction. Thrift Exception: ", e);
224
		} catch (Exception e) {
225
			log.error("Unable to update status of transaction. Thrift Exception: ", e);
226
		}
227
	}
228
 
229
	/**
230
	 * Calculates the amount for the payment required for the given transaction.
231
	 * 
232
	 * @param txnId
233
	 *            Id of the transaction for which this payment amount has to be
234
	 *            calculated.
235
	 * @return The total amount for which a payment should be created.
236
	 * @throws TransactionServiceException 
237
	 * @throws TException
238
	 */
239
	private double calculatePaymentAmount(long txnId) throws TransactionServiceException, TException{
240
		Client tc = new TransactionClient().getClient(); 
241
		double payment_amount = tc.calculatePaymentAmount(txnId);
242
		return payment_amount;
243
	}
244
 
245
	public double getOrderAmount(long txnId) throws TransactionServiceException, TException{
246
		return calculatePaymentAmount(txnId);
247
	}
248
 
249
	/**
250
	 * Removes the items processed through the given transaction from the
251
	 * shopping cart.
252
	 * 
253
	 * @param transaction
254
	 *            The transaction whose items have to be removed from the
255
	 *            shopping cart.
256
	 * @param userServiceClient
257
	 */
258
	private static long resetCart(Transaction transaction, UserClient userServiceClient) {
259
		long sum = 0;
260
		Map<Long, Double> items = new HashMap<Long, Double>();
261
		for(Order order: transaction.getOrders()){
262
			sum += order.getGvAmount();
263
			for(LineItem lineitem: order.getLineitems()){
264
				Long itemId = lineitem.getItem_id();
265
				Double quantity = items.get(itemId);
266
				if(quantity==null){
267
					quantity = lineitem.getQuantity();
268
				} else {
269
					quantity= quantity + lineitem.getQuantity();
270
				}
271
				items.put(itemId, quantity);
272
			}
273
		}
274
 
275
		log.debug("Items to reset in cart are: " + items);
276
 
277
		try {
278
			//TODO Optimize the function to send less data over the wire
279
			userServiceClient.getClient().resetCart(transaction.getShoppingCartid(), items);
280
		}catch (TException e) {
281
			log.error("Error while updating information in payment database.", e);
282
		} catch (ShoppingCartException e) {
283
			log.error("Error while reseting the cart in cart database.", e);
284
		}catch (Exception e) {
285
			log.error("Unexpected exception", e);
286
		}
287
		return sum;
288
	}
289
 
290
	/**
291
	 * Mark the coupon associated with the given transaction as used.
292
	 * 
293
	 * @param transaction
294
	 *            The transaction to track coupon for.
295
	 * 
296
	 * @param userServiceClient
297
	 *            The user service client instance to use.
298
	 */
299
	private static void trackCouponUsage(Transaction transaction, long sum) {
300
		try {
301
			String couponCode = transaction.getCoupon_code();
302
 
303
			if (couponCode != null && !couponCode.isEmpty()) {
304
				PromotionClient promotionServiceClient = new PromotionClient();
305
				promotionServiceClient.getClient().trackCouponUsage(couponCode, transaction.getId(), transaction.getCustomer_id(), sum, false);
306
			}
307
		} catch (PromotionException e) {
308
			log.error("Promotion Exception: " + e);
309
		} catch (TException e)  {
310
			log.error("Transport from Promotion Service failed:", e);
311
		} catch (Exception e) {
312
			log.error("Unexpected exception:", e);
313
		}
314
	}
315
 
316
	public boolean createPayment(RechargeOrder rechargeOrder, int gatewayId) {
317
		PaymentClient paymentServiceClient = null;
318
		try {
319
			paymentServiceClient = new PaymentClient();
320
		} catch (Exception e) {
321
			log.error("Error while getting payment client", e);
322
			return PAYMENT_NOT_CREATED;
323
		}
324
 
325
		amount = rechargeOrder.getTotalAmount() - rechargeOrder.getWalletAmount() - rechargeOrder.getCouponAmount();
326
 
327
		try {
328
			paymentId = paymentServiceClient.getClient().createPayment(rechargeOrder.getUserId(), amount, gatewayId, rechargeOrder.getTransactionId(), true);
329
			// This is being done to ensure that the amount which we pass on to
330
			// the PGs is same as what we have in the database.
331
			Payment payment = paymentServiceClient.getClient().getPayment(paymentId);
332
			amount = payment.getAmount();
333
		} catch (PaymentException e1) {
334
			log.error("Unable to create payment object.", e1);
335
			return PAYMENT_NOT_CREATED;
336
		} catch (TException e) {
337
			log.error("Not able to create payment object.", e);
338
			return PAYMENT_NOT_CREATED;
339
		}
340
 
341
		return true;
342
 
343
	}
344
 
345
	public static void main(String[] args) {
346
		Map<Long, Double> miscCharges = new HashMap<Long, Double>();
347
		miscCharges.put(1L, 3.988);
348
		System.out.println(miscCharges);
349
		if(miscCharges != null & !miscCharges.isEmpty()){
350
			System.out.println( miscCharges.get(1L));;
351
		}
352
	}
353
 
354
	/*	private static OrderType getOrderType(Long userId) throws TTransportException, TException{
355
		OrderType ot = OrderType.B2C;
356
		try {
357
 
358
			in.shop2020.model.v1.user.UserContextService.Client uc = new UserClient().getClient();
359
			uc.tax
360
			PrivateDealUser pdu = uc.getPrivateDealUser(userId);
361
			if(pdu.getTin() != null && !pdu.getTin().trim().equals("")){
362
				ot = OrderType.B2B;
363
			}
364
		} catch (TTransportException e) {
365
			log.error("Unable to get user service client.", e);	
366
		}
367
		return ot;
368
	}*/
369
}