Subversion Repositories SmartDukaan

Rev

Rev 13521 | Details | Compare with Previous | Last modification | View Log | RSS feed

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