Subversion Repositories SmartDukaan

Rev

Rev 4022 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/**
 * 
 */
package in.shop2020.crm.util;

import in.shop2020.crm.domain.Activity;
import in.shop2020.crm.domain.SearchFilter;
import in.shop2020.crm.domain.Ticket;
import in.shop2020.crm.ActivityType;
import in.shop2020.crm.TicketCategory;
import in.shop2020.crm.TicketPriority;
import in.shop2020.crm.TicketStatus;
import in.shop2020.crm.handler.ActivityHandler;
import in.shop2020.crm.handler.TicketHandler;
import in.shop2020.model.v1.order.ExtraTransactionProcessingType;
import in.shop2020.model.v1.order.Order;
import in.shop2020.model.v1.order.OrderStatus;
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.user.User;
import in.shop2020.model.v1.user.UserContextException;
import in.shop2020.thrift.clients.TransactionClient;
import in.shop2020.thrift.clients.UserClient;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author mandeep
 * Processor all the COD transactions booked by customers, creates a ticket per
 * customer so as our Outbound team can work on them like verifying users
 * validity and order details.
 */
public class CODTransactionProcessorTask implements Runnable {
    private static Log log = LogFactory.getLog(CODTransactionProcessorTask.class);
    private static final double TRUST_THRESHOLD_LEVEL = 4.5;
    private static final long   ADMIN_AGENT_ID   = 1;
    private static final long   OUTBOUND_DEFAULT_ASSIGNEE_ID   = 12;

    private TicketHandler      ticketHandler;
    private ActivityHandler    activityHandler;

    public CODTransactionProcessorTask(TicketHandler ticketHandler,
            ActivityHandler activityHandler)
    {
        this.ticketHandler = ticketHandler;
        this.activityHandler = activityHandler;
    }

    /* (non-Javadoc)
     * @see java.lang.Runnable#run()
     */
    public void run() {
        try {
            Client client = new TransactionClient().getClient();
            List<Long> transactionIds = client.getTransactionsRequiringExtraProcessing(ExtraTransactionProcessingType.COD_VERIFICATION);
            if (transactionIds != null && !transactionIds.isEmpty()) {
                log.info("Fetched " + transactionIds.size() + " transactions");
                for (Long transactionId : transactionIds) {
                    processCODTxn(transactionId);
                    client.markTransactionAsProcessed(transactionId, ExtraTransactionProcessingType.COD_VERIFICATION);
                }
            }
            else {
                log.info("No transactions to process");
            }
        } catch (TTransportException e) {
            log.error("Could not create TransactionService client", e);
        } catch (TException e) {
            log.error("Could not fetch transactions for processing", e);
        }
    }

    /**
     * Method that creates a ticket if necessary for COD verification
     */
    private void processCODTxn(long transactionId) {
        try {
            log.info("Processing txn id: " + transactionId);
            Client client = new TransactionClient().getClient();
            Transaction transaction = client.getTransaction(transactionId);
            in.shop2020.model.v1.user.UserContextService.Client userClient = new UserClient().getClient();
            User user = userClient.getUserById(transaction.getCustomer_id());
            if (user.getTrustLevel() - TRUST_THRESHOLD_LEVEL < 1e-4) {
                for (Order order : transaction.getOrders()) {
                    log.info("Processing order: " + order.getId());
                    if (order.isCod() && OrderStatus.INIT.equals(order.getStatus())) {
                        log.info("Processing COD order: " + order.getId());
                        in.shop2020.crm.domain.SearchFilter searchFilter = new SearchFilter();
                        searchFilter.setTicketStatuses(new ArrayList<TicketStatus>());
                        searchFilter.getTicketStatuses().add(TicketStatus.OPEN);
                        searchFilter.getTicketStatuses().add(TicketStatus.REOPEN);
                        searchFilter.setTicketCategory(TicketCategory.COD_VERIFICATION);
                        searchFilter.setCustomerId(transaction.getCustomer_id());

                        // No need to create a ticket if there exists one for the customer!
                        if (ticketHandler.getTickets(searchFilter).isEmpty()) {
                            log.info("Logging ticket");
                            Ticket ticket = new Ticket();
                            ticket.setCategory(TicketCategory.COD_VERIFICATION);
                            ticket.setCreatorId(ADMIN_AGENT_ID);
                            ticket.setCustomerId(transaction.getCustomer_id());
                            ticket.setDescription("Requires COD verification");
                            ticket.setPriority(TicketPriority.HIGH);
                            ticket.setStatus(TicketStatus.OPEN);
                            ticket.setAssigneeId(OUTBOUND_DEFAULT_ASSIGNEE_ID);

                            Activity activity = new Activity();
                            activity.setCreatorId(ticket.getCreatorId());
                            activity.setCustomerId(ticket.getCustomerId());
                            activity.setDescription("Creating ticket");
                            activity.setTicketCategory(ticket.getCategory());
                            activity.setTicketDescription(ticket.getDescription());
                            activity.setTicketPriority(ticket.getPriority());
                            activity.setTicketStatus(ticket.getStatus());
                            activity.setTicketAssigneeId(ticket.getAssigneeId());
                            activity.setType(ActivityType.OTHER);

                            createTicket(ticket, activity);
                            break;
                        }
                    }
                }
            }
            else {
                log.info("Autoverifying orders");
                // Submit order for processing
                for (Order order : transaction.getOrders()) {
                    log.info("Processing order: " + order.getId());
                    client.changeOrderStatus(order.getId(), OrderStatus.SUBMITTED_FOR_PROCESSING, "In Process");
                }
            }
        } catch (TransactionServiceException e) {
            log.error("Could not fetch transaction details", e);
        } catch (UserContextException e) {
            log.error("Could not fetch user details", e);
        } catch (TException e) {
            log.info("Error processing txn id: " + transactionId);
        } catch (Exception e) {
            log.info("Exception processing txn id: " + transactionId);
        }
    }

    @Transactional
    private void createTicket(Ticket ticket, Activity activity) {
        ticketHandler.insertTicket(ticket);
        activityHandler.insertActivity(activity);
    }
}