Subversion Repositories SmartDukaan

Rev

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

/**
 * 
 */
package in.shop2020.crm.service.handler;

import in.shop2020.crm.Activity;
import in.shop2020.crm.ActivityType;
import in.shop2020.crm.Agent;
import in.shop2020.crm.CRMService.Iface;
import in.shop2020.crm.SearchFilter;
import in.shop2020.crm.Ticket;
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.AgentHandler;
import in.shop2020.crm.handler.TicketHandler;
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.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.thrift.TException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Implementation of the interface/services exposed by thrift to clients!
 * 
 * @author mandeep
 */
@Service
public class CRMServiceHandler implements Iface {
    public static final long   ADMIN_AGENT_ID   = 1;
    public static final long   OUTBOUND_DEFAULT_ASSIGNEE_ID   = 12;
    ApplicationContext context         = new ClassPathXmlApplicationContext(
                                               "context.xml");
    TicketHandler      ticketHandler   = context.getBean(TicketHandler.class);
    ActivityHandler    activityHandler = context.getBean(ActivityHandler.class);
    AgentHandler       agentHandler    = context.getBean(AgentHandler.class);

    private static final Log log = LogFactory.getLog(CRMServiceHandler.class);
    private static final double TRUST_THRESHOLD_LEVEL = 4.5;

    public List<Ticket> getTickets(SearchFilter searchFilter) throws TException {
        List<Ticket> ttickets = new ArrayList<Ticket>();
        for (in.shop2020.crm.domain.Ticket ticket : ticketHandler
                .getTickets(in.shop2020.crm.domain.SearchFilter
                        .create(searchFilter))) {
            ttickets.add(ticket.getThriftTicket());
        }

        return ttickets;
    }

    public List<Ticket> getUnassignedTickets() throws TException {
        List<Ticket> tickets = new ArrayList<Ticket>();

        for (in.shop2020.crm.domain.Ticket ticket : ticketHandler
                .getUnassignedTickets()) {
            tickets.add(ticket.getThriftTicket());
        }

        return tickets;
    }

    @Transactional
    public void updateTicket(Ticket ticket, Activity activity)
            throws TException {
        try {
            ticketHandler.updateTicket(in.shop2020.crm.domain.Ticket
                    .create(ticket));
            activity.setTicketId(ticket.getId());
            activityHandler.insertActivity(in.shop2020.crm.domain.Activity
                    .create(activity));
        } catch (ParseException e) {
            throw new TException("Could not update " + ticket, e);
        }
    }

    @Transactional
    public long insertTicket(Ticket ticket, Activity activity)
            throws TException {
        try {
            long ticketId = ticketHandler
                    .insertTicket(in.shop2020.crm.domain.Ticket.create(ticket));
            activity.setTicketId(ticketId);
            activityHandler.insertActivity(in.shop2020.crm.domain.Activity
                    .create(activity));
            return ticketId;
        } catch (ParseException e) {
            throw new TException("Could not insert " + ticket, e);
        }
    }

    public List<Activity> getActivities(SearchFilter searchFilter)
            throws TException {
        List<Activity> tactivities = new ArrayList<Activity>();
        List<in.shop2020.crm.domain.Activity> activities = activityHandler
                .getActivities(in.shop2020.crm.domain.SearchFilter
                        .create(searchFilter));

        if (activities != null) {
            for (in.shop2020.crm.domain.Activity ticket : activities) {
                tactivities.add(ticket.getThriftActivity());
            }
        }

        return tactivities;
    }

    public long insertActivity(Activity activity) throws TException {
        try {
            return activityHandler.insertActivity(in.shop2020.crm.domain.Activity
                    .create(activity));
        } catch (ParseException e) {
            throw new TException("Could not insert " + activity, e);
        }
    }

    @Transactional
    public void markAsRead(long activityId, long agentId) throws TException {
        in.shop2020.crm.domain.SearchFilter searchFilter = new in.shop2020.crm.domain.SearchFilter();
        searchFilter.setActivityId(activityId);
        activityHandler.markAsRead(activityId);
        in.shop2020.crm.domain.Activity activity = activityHandler
                .getActivities(searchFilter).get(0);
        activity.setCreatorId(agentId);
        activity.setDescription("Marked as read ticketId: "
                + activity.getTicketId() + ", activityId: " + activityId);
        activity.setType(ActivityType.OTHER);
        activityHandler.insertActivity(activity);
    }

    public List<Agent> getAgents(SearchFilter searchFilter) throws TException {
        List<Agent> agents = new ArrayList<Agent>();

        for (in.shop2020.crm.domain.Agent agent : agentHandler
                .getAgents(in.shop2020.crm.domain.SearchFilter
                        .create(searchFilter))) {
            agents.add(agent.getThriftAgent());
        }

        return agents;
    }

    public void updatePasswordForAgent(String agentEmailId, String password)
            throws TException {
        agentHandler.updatePasswordForAgent(agentEmailId, password);
    }

    public long getLastEmailProcessedTimestamp() throws TException {
        return agentHandler.getLastEmailProcessedTimestamp().getTime();
    }

    public void updateLastEmailProcessedTimestamp(long timestamp)
            throws TException {
        agentHandler.updateLastEmailProcessedTimestamp(new Date(timestamp));
    }

    public List<String> getRoleNamesForAgent(String agentEmailId)
            throws TException {
        return agentHandler.getRoleNamesForAgent(agentEmailId);
    }

    public List<String> getPermissionsForRoleName(String roleName)
            throws TException {
        return agentHandler.getPermissionsForRoleName(roleName);
    }

        public boolean isAlive() throws TException {
                // TODO Auto-generated method stub
                return true;
        }

        public void closeSession() throws TException {
                // TODO Auto-generated method stub
                
        }

        /**
         * Async method that creates a ticket if necessary for COD verification
         */
    public 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());
                        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 (this.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);

                            this.insertTicket(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);
        }
    }

    /**
     * Async method to create tickets for failed payments.
     */
    public void processPaymentFailure(long customerId) {
        try {
            log.info("Processing Payment failure for customerId: " + customerId);
            SearchFilter searchFilter = new SearchFilter();
            searchFilter.setTicketStatuses(new ArrayList<TicketStatus>());
            searchFilter.getTicketStatuses().add(TicketStatus.OPEN);
            searchFilter.getTicketStatuses().add(TicketStatus.REOPEN);
            searchFilter.setTicketCategory(TicketCategory.FAILED_PAYMENTS);
            searchFilter.setCustomerId(customerId);

            // No need to create a ticket if there exists one for the customer!
            if (this.getTickets(searchFilter).isEmpty()) {
                Ticket ticket = new Ticket();
                ticket.setCategory(TicketCategory.FAILED_PAYMENTS);
                ticket.setCreatorId(ADMIN_AGENT_ID);
                ticket.setCustomerId(customerId);
                ticket.setDescription("Requires payment failures' follow-up!");
                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.setType(ActivityType.OTHER);
                activity.setTicketAssigneeId(ticket.getAssigneeId());

                this.insertTicket(ticket, activity);
            }
        } catch (TException e) {
            log.error("Error fetching/inserting tickets for customer Id: " + customerId, e);
        } catch (Exception e) {
            log.error("Exception processing payment failrue for customer Id: " + customerId, e);
        }
    }
}