Rev 22587 | Rev 28653 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.spice.profitmandi.web.controller.checkout;import java.util.HashMap;import java.util.Map;import org.apache.thrift.TException;import org.apache.thrift.transport.TTransportException;import org.apache.logging.log4j.Logger;import org.apache.logging.log4j.LogManager;import com.spice.profitmandi.thrift.clients.PaymentClient;import com.spice.profitmandi.thrift.clients.PromotionClient;import com.spice.profitmandi.thrift.clients.TransactionClient;import com.spice.profitmandi.thrift.clients.UserClient;import in.shop2020.logistics.PickUpType;import in.shop2020.model.v1.order.LineItem;import in.shop2020.model.v1.order.Order;import in.shop2020.model.v1.order.OrderSource;import in.shop2020.model.v1.order.OrderType;import in.shop2020.model.v1.order.RechargeOrder;import in.shop2020.model.v1.order.Transaction;import in.shop2020.model.v1.order.TransactionService.Client;import in.shop2020.model.v1.order.TransactionServiceException;import in.shop2020.model.v1.order.TransactionStatus;import in.shop2020.model.v1.user.PromotionException;import in.shop2020.model.v1.user.ShoppingCartException;import in.shop2020.payments.Payment;import in.shop2020.payments.PaymentException;import in.shop2020.payments.PaymentGateway;/*** This class has methods to be used to process non-gateway-specific aspects of* payments and transactions.** @author Chandranshu**/public class CommonPaymentService {private static final boolean PAYMENT_NOT_CREATED = false;private static final Logger log = LogManager.getLogger(CommonPaymentService.class);private static Map<Integer, PaymentGateway> PAYMENT_GATEWAYS;private long paymentId;private double amount;public long getPaymentId() {return paymentId;}public double getAmount() {return amount;}/*** Creates a payment for the given cart of the given user for the given* transaction. Stores the id of the newly created payment and the amount* for which this payment was created. They can be retrieved later on using* {@link #getPaymentId()}getPaymentId() and {@link #getAmount()}getAmount()* methods respectively later on.** @param userId* The user for whom the payment has to be created.* @param txnId* The transaction against which the payment has to be created.* @param gatewayId* @return True if the payment object is successfully created, False* otherwise.*/public boolean createPayment(long userId, long txnId, int gatewayId) {TransactionClient transactionClient = null;Client tc = null;try {transactionClient = new TransactionClient();tc = transactionClient.getClient();} catch (TTransportException e) {log.error("Unable to create transaction client", e);return PAYMENT_NOT_CREATED;}try {amount = calculatePaymentAmount(txnId);} catch (Exception e1) {log.error("Unable to calcuate payment amount", e1);return PAYMENT_NOT_CREATED;}try {paymentId = tc.createPayment(userId, txnId, gatewayId);} catch (TException e) {log.error("Unable to create payment", e);return PAYMENT_NOT_CREATED;}return true;}// TODO: The service client parameters in the processSuccessfulTxn et al are// unnecessary but initializing them again when the caller has the necessary// references has a performance overhead. Need to think more about this./*** Processes a successful transaction by:* <ol>* <li>Marking the given transaction as 'authorized'.</li>* <li>Removing the items in the cart for which the given transaction was* processed.</li>* <li>Marking the coupon associated with this transaction, if any, as used* for this user.</li>* <li>Queuing the transaction successful email, containing transaction* info, to be sent later by a batch job.</li>* </ol>* <br>* Please note that it's possible that a user has added items to the cart* and so it's not possible to simply wipe out their cart. Therefore, it's* important to ensure that we remove only as much quantity of items as for* which the order was processed.** @param txnId* The transaction which should be marked as successful.* @param userServiceClient* A user context service client to use.* @param transactionServiceClient* A transaction service client to use.* @param isFlagged* If payment is flagged it will be true else false*/public static void processSuccessfulTxn(long txnId, UserClient userServiceClient,TransactionClient transactionServiceClient, boolean isFlagged) {Transaction transaction = null;TransactionStatus tStatus = TransactionStatus.AUTHORIZED;String description = "Payment authorized for the order";// if flag is set, status to be changed to flaggedif (isFlagged) {tStatus = TransactionStatus.FLAGGED;description = "Payment flagged for the order";}try {PickUpType pickupType = PickUpType.COURIER;in.shop2020.model.v1.order.TransactionService.Client transactionClient = transactionServiceClient.getClient();transaction = transactionClient.getTransaction(txnId);if (transaction.getOrders().get(0).getLogistics_provider_id() == 4 ){pickupType = PickUpType.SELF;} else if (transaction.getOrders().get(0).getLogistics_provider_id()==5) {pickupType = PickUpType.RUNNER;}log.info("Pickup type is -- {}", pickupType.getValue());transactionClient.changeTransactionStatus(txnId, tStatus, description, pickupType.getValue(), null,null);transactionClient.enqueueTransactionInfoEmail(txnId);} catch (TException e1) {log.error("Unable to update status of transaction. Thrift Exception:", e1);} catch (TransactionServiceException e) {log.error("Unable to update status of transaction. Thrift Exception: ", e);}long sum = resetCart(transaction, userServiceClient);trackCouponUsage(transaction, sum);}/*** Marks a transaction as well as all its orders as failed.** @param txnId* The id of the transaction which has to be marked as failed.* @param transactionServiceClient*/public static void processFailedTxn(long txnId, TransactionClient transactionServiceClient) {try {in.shop2020.model.v1.order.TransactionService.Client transactionClient = transactionServiceClient.getClient();transactionClient.changeTransactionStatus(txnId, TransactionStatus.FAILED,"Payment failed for the transaction.", PickUpType.COURIER.getValue(), OrderType.B2C,OrderSource.WEBSITE);} catch (TException e) {log.error("Thrift exception while getting information from transaction service.", e);} catch (TransactionServiceException e) {log.error("Error while updating status information in transaction database.", e);}}/*** Processes a COD transaction by:* <ol>* <li>Setting the COD flag of all the orders and moving them to the INIT* state.* <li>Marking the given transaction to be in COD_IN_PROCESS state* <li>Marking the coupon associated with this transaction, if any, as used* for this user.</li>* <li>Queuing the transaction successful email, containing transaction* info, to be sent later by a batch job.</li>* </ol>* <br>* Please note that it's possible that a user has added items to the cart* and so it's not possible to simply wipe out their cart. Therefore, it's* important to ensure that we remove only as much quantity of items as for* which the order was processed.** @param txnId* The COD transaction which should be marked as verification* pending.*/public static void processCodTxn(long txnId, OrderType orderType) {try {TransactionClient transactionServiceClient = new TransactionClient();in.shop2020.model.v1.order.TransactionService.Client transactionClient = transactionServiceClient.getClient();transactionClient.changeTransactionStatus(txnId, TransactionStatus.COD_IN_PROCESS, "COD payment awaited",PickUpType.COURIER.getValue(), orderType, OrderSource.WEBSITE);Transaction transaction = transactionClient.getTransaction(txnId);transactionClient.enqueueTransactionInfoEmail(txnId);UserClient userServiceClient = new UserClient();long sum = resetCart(transaction, userServiceClient);trackCouponUsage(transaction, sum);} catch (TException e1) {log.error("Unable to update status of transaction. Thrift Exception:", e1);} catch (TransactionServiceException e) {log.error("Unable to update status of transaction. Thrift Exception: ", e);} catch (Exception e) {log.error("Unable to update status of transaction. Thrift Exception: ", e);}log.info("successfully processed cod transaction");}public static void processCouponTxn(long txnId, OrderType orderType) {try {TransactionClient transactionServiceClient = new TransactionClient();in.shop2020.model.v1.order.TransactionService.Client transactionClient = transactionServiceClient.getClient();transactionClient.changeTransactionStatus(txnId, TransactionStatus.AUTHORIZED,"Payment by coupon successful", PickUpType.COURIER.getValue(), orderType, OrderSource.WEBSITE);Transaction transaction = transactionClient.getTransaction(txnId);UserClient userServiceClient = new UserClient();long sum = resetCart(transaction, userServiceClient);trackCouponUsage(transaction, sum);} catch (TException e1) {log.error("Unable to update status of transaction. Thrift Exception:", e1);} catch (TransactionServiceException e) {log.error("Unable to update status of transaction. Thrift Exception: ", e);} catch (Exception e) {log.error("Unable to update status of transaction. Thrift Exception: ", e);}}/*** Calculates the amount for the payment required for the given transaction.** @param txnId* Id of the transaction for which this payment amount has to be* calculated.* @return The total amount for which a payment should be created.* @throws TransactionServiceException* @throws TException*/private double calculatePaymentAmount(long txnId) throws TransactionServiceException, TException {Client tc = new TransactionClient().getClient();double payment_amount = tc.calculatePaymentAmount(txnId);return payment_amount;}public double getOrderAmount(long txnId) throws TransactionServiceException, TException {return calculatePaymentAmount(txnId);}/*** Removes the items processed through the given transaction from the* shopping cart.** @param transaction* The transaction whose items have to be removed from the* shopping cart.* @param userServiceClient*/private static long resetCart(Transaction transaction, UserClient userServiceClient) {long sum = 0;Map<Long, Double> items = new HashMap<Long, Double>();for (Order order : transaction.getOrders()) {sum += order.getGvAmount();for (LineItem lineitem : order.getLineitems()) {Long itemId = lineitem.getItem_id();Double quantity = items.get(itemId);if (quantity == null) {quantity = lineitem.getQuantity();} else {quantity = quantity + lineitem.getQuantity();}items.put(itemId, quantity);}}log.debug("Items to reset in cart are: " + items);try {// TODO Optimize the function to send less data over the wireuserServiceClient.getClient().resetCart(transaction.getShoppingCartid(), items);} catch (TException e) {log.error("Error while updating information in payment database.", e);} catch (ShoppingCartException e) {log.error("Error while reseting the cart in cart database.", e);} catch (Exception e) {log.error("Unexpected exception", e);}return sum;}/*** Mark the coupon associated with the given transaction as used.** @param transaction* The transaction to track coupon for.** @param userServiceClient* The user service client instance to use.*/private static void trackCouponUsage(Transaction transaction, long sum) {try {String couponCode = transaction.getCoupon_code();if (couponCode != null && !couponCode.isEmpty()) {PromotionClient promotionServiceClient = new PromotionClient();promotionServiceClient.getClient().trackCouponUsage(couponCode, transaction.getId(),transaction.getCustomer_id(), sum, false);}} catch (PromotionException e) {log.error("Promotion Exception: " + e);} catch (TException e) {log.error("Transport from Promotion Service failed:", e);} catch (Exception e) {log.error("Unexpected exception:", e);}}public boolean createPayment(RechargeOrder rechargeOrder, int gatewayId) {PaymentClient paymentServiceClient = null;try {paymentServiceClient = new PaymentClient();} catch (Exception e) {log.error("Error while getting payment client", e);return PAYMENT_NOT_CREATED;}amount = rechargeOrder.getTotalAmount() - rechargeOrder.getWalletAmount() - rechargeOrder.getCouponAmount();try {paymentId = paymentServiceClient.getClient().createPayment(rechargeOrder.getUserId(), amount, gatewayId,rechargeOrder.getTransactionId(), true);// This is being done to ensure that the amount which we pass on to// the PGs is same as what we have in the database.Payment payment = paymentServiceClient.getClient().getPayment(paymentId);amount = payment.getAmount();} catch (PaymentException e1) {log.error("Unable to create payment object.", e1);return PAYMENT_NOT_CREATED;} catch (TException e) {log.error("Not able to create payment object.", e);return PAYMENT_NOT_CREATED;}return true;}public static PaymentGateway getPaymentGatewayById(int gatewayId) {if (PAYMENT_GATEWAYS == null || PAYMENT_GATEWAYS.isEmpty()) {PaymentClient paymentServiceClient = null;PAYMENT_GATEWAYS = new HashMap<>();try {paymentServiceClient = new PaymentClient();for (PaymentGateway pg : paymentServiceClient.getClient().getActivePaymentGateways()){PAYMENT_GATEWAYS.put((int)pg.getId(), pg);}} catch (Exception e) {log.error("Error while getting payment client", e);}}return PAYMENT_GATEWAYS.get(gatewayId);}public static void main(String[] args) {Map<Long, Double> miscCharges = new HashMap<Long, Double>();miscCharges.put(1L, 3.988);System.out.println(miscCharges);if (miscCharges != null & !miscCharges.isEmpty()) {System.out.println(miscCharges.get(1L));;}}/** private static OrderType getOrderType(Long userId) throws* TTransportException, TException{ OrderType ot = OrderType.B2C; try {** in.shop2020.model.v1.user.UserContextService.Client uc = new* UserClient().getClient(); uc.tax PrivateDealUser pdu =* uc.getPrivateDealUser(userId); if(pdu.getTin() != null &&* !pdu.getTin().trim().equals("")){ ot = OrderType.B2B; } } catch* (TTransportException e) { log.error("Unable to get user service client.",* e); } return ot; }*/}