Subversion Repositories SmartDukaan

Rev

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

/**
 * 
 */
package in.shop2020.serving.controllers;

import in.shop2020.crm.Activity;
import in.shop2020.crm.ActivityType;
import in.shop2020.crm.Agent;
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.model.v1.order.LineItem;
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.TransactionServiceException;
import in.shop2020.model.v1.order.TransactionStatus;
import in.shop2020.model.v1.user.User;
import in.shop2020.model.v1.user.UserContextException;
import in.shop2020.payments.Payment;
import in.shop2020.payments.PaymentException;
import in.shop2020.payments.PaymentStatus;
import in.shop2020.serving.auth.CRMAuthorizingRealm;
import in.shop2020.thrift.clients.CRMClient;
import in.shop2020.thrift.clients.HelperClient;
import in.shop2020.thrift.clients.PaymentClient;
import in.shop2020.thrift.clients.TransactionClient;
import in.shop2020.thrift.clients.UserClient;
import in.shop2020.util.CRMConstants;
import in.shop2020.util.CRMConstants.EscalationMatrix;
import in.shop2020.utils.HelperService.Client;
import in.shop2020.utils.HelperServiceException;
import in.shop2020.utils.ModelUtils;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import net.htmlparser.jericho.Source;

import org.apache.shiro.SecurityUtils;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;

/**
 * @author mandeep
 * 
 */
public class TicketsController extends BaseController {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    List<Ticket>              tickets          = new ArrayList<Ticket>();
    private String            customerEmailId;
    private String            description;
    private String            assigneeEmailId;
    private String            priority;
    private String            category;
    private String            orderId;
    private String[]          agentIds;
    private String            startTimestamp;
    private String            endTimestamp;

    private String            userId;
    private String            id;
    private String            activityDescription;
    private String            status;
    private String            activityType;
    private Ticket            ticket;
    private List<Activity>    activities;
    private String            subject;
    private String            body;
    private String            customerName;
    private String            customerMobileNumber;
    private User              user;
    private String            orderStatus;
    private List<Order>       orders;
    private List<Payment>     payments;
    private String            escalate;
    private String            cancelReason;
    private String            transactionId;

    private String paymentId;

    private HashMap<String, String> allAttachmentsForTicket;

    public String index() {
        try {
            if (id != null && !id.isEmpty()) {
                SearchFilter searchFilter = new SearchFilter();
                crmServiceClient = new CRMClient().getClient();
                searchFilter.setTicketId(Long.parseLong(id));
                tickets = crmServiceClient.getTickets(searchFilter);
            }
        } catch (TException e) {
            log.error("Error while getting tickets", e);
            return EXCEPTION;
        }

        return INDEX;
    }

    public String edit() {
        try {
            long ticketId = Long.parseLong(id);
            SearchFilter searchFilter = new SearchFilter();
            searchFilter.setTicketId(ticketId);
            crmServiceClient = new CRMClient().getClient();
            ticket = crmServiceClient.getTickets(searchFilter).get(0);
            activities = crmServiceClient.getActivities(searchFilter);
            populateAttachments();
            subject = createSubjectString(ticket);

            if (ticket.isSetCustomerId()) {
                userId = String.valueOf(ticket.getCustomerId());
                userContextServiceClient = new UserClient().getClient();

                try {
                    user = userContextServiceClient.getUserById(ticket
                            .getCustomerId());
                } catch (UserContextException e) {
                    log.error("Could not fetch user details", e);
                }
            }

            customerEmailId = ticket.getCustomerEmailId();

            if (TicketCategory.ORDER_CANCELLATION.equals(ticket.getCategory())) {
                log.info("Fetching orders for " + ticket.getCustomerId());
                orders = new ArrayList<Order>();
                transactionServiceClient = new TransactionClient().getClient();
                for (Order order : transactionServiceClient
                        .getOrdersForCustomer(ticket.getCustomerId(), 0, 0,
                                Collections.singletonList(OrderStatus.CANCEL_REQUEST_RECEIVED))) {
                    log.info("Processing Order: " + order.getId());
                    orders.add(order);
                }
            }

            if (TicketCategory.COD_VERIFICATION.equals(ticket.getCategory())) {
                log.info("Fetching orders for " + ticket.getCustomerId());
                orders = new ArrayList<Order>();
                transactionServiceClient = new TransactionClient().getClient();
                for (Order order : transactionServiceClient
                        .getOrdersForCustomer(ticket.getCustomerId(), 0, 0,
                                Collections.singletonList(OrderStatus.COD_VERIFICATION_PENDING))) {
                    log.info("Processing Order: " + order);
                    if (order.isCod()) {
                        orders.add(order);
                    }
                }
            }

            if (TicketCategory.DOA_RECEIVED.equals(ticket.getCategory())) {
                log.info("Fetching orders for " + ticket.getCustomerId());
                orders = new ArrayList<Order>();
                transactionServiceClient = new TransactionClient().getClient();
                for (Order order : transactionServiceClient
                        .getOrdersForCustomer(ticket.getCustomerId(), 0, 0,
                                Collections.singletonList(OrderStatus.DOA_REQUEST_RECEIVED))) {
                    log.info("Processing Order: " + order);
                    if (order != null) {
                        orders.add(order);
                    }
                }
            }

            if (TicketCategory.RETURN_FORM.equals(ticket.getCategory())) {
                log.info("Fetching orders for " + ticket.getCustomerId());
                orders = new ArrayList<Order>();
                transactionServiceClient = new TransactionClient().getClient();
                for (Order order : transactionServiceClient
                        .getOrdersForCustomer(ticket.getCustomerId(), 0, 0,
                                Collections.singletonList(OrderStatus.RET_REQUEST_RECEIVED))) {
                    log.info("Processing Order: " + order);
                    if (order != null) {
                        orders.add(order);
                    }
                }
            }

            if (TicketCategory.PAYMENT_FLAGGED.equals(ticket.getCategory())) {
                log.info("Fetching orders for " + ticket.getCustomerId());
                payments = new ArrayList<Payment>();
                in.shop2020.payments.PaymentService.Client paymentClient = new PaymentClient().getClient();
                transactionServiceClient = new TransactionClient().getClient();
                for (Transaction transaction : transactionServiceClient
                        .getTransactionsForCustomer(ticket.getCustomerId(), 0, 0, TransactionStatus.FLAGGED)) {
                    log.info("Processing Transaction: " + transaction);
                    for ( Payment payment : paymentClient.getPaymentForTxnId(transaction.getId())) {
                        if( payment.getStatus().equals(PaymentStatus.AUTHORIZED)) {
                            payments.add(payment);
                        }
                    }
                }
            }

            if (TicketCategory.FAILED_PAYMENTS.equals(ticket.getCategory())) {
                log.info("Fetching orders for " + ticket.getCustomerId());
                orders = new ArrayList<Order>();
                in.shop2020.payments.PaymentService.Client paymentClient = new PaymentClient().getClient();

                long failedTransactionId = -1;
                long lastfailedTransactionTimestamp = -1;
                for (Payment payment : paymentClient.getPaymentsForUser(ticket.getCustomerId(), 0, getTomorrow().getTime(), PaymentStatus.FAILED, 0)) {
                    if (payment.getErrorTimestamp() > lastfailedTransactionTimestamp) {
                        failedTransactionId = payment.getMerchantTxnId();
                    }
                }

                transactionServiceClient = new TransactionClient().getClient();
                orders.addAll(transactionServiceClient.getOrdersForTransaction(failedTransactionId, ticket.getCustomerId()));
            }

            if (TicketCategory.DELAYED_DELIVERY.equals(ticket.getCategory())) {
                log.info("Fetching orders for " + ticket.getCustomerId());
                orders = new ArrayList<Order>();
                transactionServiceClient = new TransactionClient().getClient();

                for (Order order : transactionServiceClient.getOrdersForCustomer(ticket.getCustomerId(), 0, 0, null)) {
                    if (order.getExpected_delivery_time() > order.getPromised_delivery_time() && order.getExpected_delivery_time() > new Date().getTime()) {
                        orders.add(order);
                    }
                }
            }
        } catch (TException e) {
            log.error("Error loading edit page", e);
        } catch (NumberFormatException e) {
            log.error("Error parsing orderId", e);
        } catch (TransactionServiceException e) {
            log.error("Error fetching orders for " + ticket.getCustomerId(), e);
        } catch (PaymentException e) {
            log.error("Error fetching payments for " + ticket.getCustomerId(), e);
        }

        return EDIT;
    }

    private void populateAttachments() {
        allAttachmentsForTicket = new HashMap<String, String>();
        for (Activity activity : activities) {
            log.info("" + activity.getId());
            String attachment = activity.getAttachments();
            if (attachment != null && !attachment.isEmpty()) {
                log.info("" + attachment);
                String [] attachmentList = attachment.split(";");
                for (String attachmentName : attachmentList) {
                    if (attachmentName != null && !attachmentName.isEmpty()) {
                        log.info("" + attachmentName);
                        allAttachmentsForTicket.put(activity.getId() + "-" + attachmentName, attachmentName);
                    }
                }
            }
        }
    }
    
    public static void main(String[] args) {
        TicketsController tc = new TicketsController();
        Integer i = new Integer(14215);
        tc.id = i.toString();
        tc.populateAttachments();
    }

    private String createSubjectString(Ticket ticket) {
        return CRMConstants.CRM_SUBJECT_PREFIX_FOR_TICKET_ID + ticket.getId()
                + " " + ticket.getCategory().name();
    }

    private Date getTomorrow() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    public String create() {
        try {
            long creatorId = CRMAuthorizingRealm.getAgent(currentAgentEmailId)
                    .getId();
            Ticket ticket = new Ticket();
            ticket.setDescription(description);
            ticket.setCreatorId(creatorId);
            ticket.setStatus(TicketStatus.OPEN);
            ticket.setPriority(TicketPriority.valueOf(priority));
            ticket.setCategory(TicketCategory.valueOf(category));

            Activity activity = new Activity();
            activity.setDescription("Creating Ticket");
            activity.setType(ActivityType.OTHER);
            activity.setTicketPriority(TicketPriority.valueOf(priority));
            activity.setTicketStatus(TicketStatus.OPEN);
            activity.setCreatorId(creatorId);
            activity.setTicketCategory(TicketCategory.valueOf(category));
            activity.setTicketDescription(description);

            if (orderId != null && !orderId.isEmpty()) {
                ticket.setOrderId(Long.parseLong(orderId));
            }
            
            if (TicketCategory.valueOf(category) == TicketCategory.DOA_RECEIVED) {
                transactionServiceClient = new TransactionClient().getClient();
                if (!transactionServiceClient.markOrderDoaRequestReceived(Long.parseLong(orderId))) {
                    throw new Exception("Order cannot be marked as DOA Received");
                }
                log.info("" + userId);
                
                Order order = transactionServiceClient.getOrder(Long.parseLong(orderId));
                log.info("In order table id is : " + order.getCustomer_id());
                if (userId == null || userId.isEmpty() || order.getCustomer_id() != Long.parseLong(userId)) {
                    throw new Exception("This order is not associated with this user Id");
                }
            }
            
            if (TicketCategory.valueOf(category) == TicketCategory.RETURN_FORM) {
                transactionServiceClient = new TransactionClient().getClient();
                if (!transactionServiceClient.markOrderReturnRequestReceived(Long.parseLong(orderId))) {
                    throw new Exception("Order cannot be marked as Return Requested");
                }
                log.info("" + userId);
                
                Order order = transactionServiceClient.getOrder(Long.parseLong(orderId));
                log.info("In order table id is : " + order.getCustomer_id());
                if (userId == null || userId.isEmpty() || order.getCustomer_id() != Long.parseLong(userId)) {
                    throw new Exception("This order is not associated with this user Id");
                }
            }
            if(body!=null && !body.isEmpty()){
                String plainTextbody = new Source(body).getTextExtractor().toString();
                ticket.setDescription(description + " : " + plainTextbody);
            }
            
            if (userId != null && !userId.isEmpty()) {
                ticket.setCustomerId(Long.parseLong(userId));
                activity.setCustomerId(Long.parseLong(userId));
            } else {
                User user = null;
                userContextServiceClient = new UserClient().getClient();
                try {
                    if (customerName != null && !customerName.isEmpty()) {
                        ticket.setCustomerName(customerName);
                        activity.setCustomerName(customerName);
                    }

                    if (customerEmailId != null && !customerEmailId.isEmpty()) {
                        ticket.setCustomerEmailId(customerEmailId);
                        activity.setCustomerEmailId(customerEmailId);
                        user = userContextServiceClient
                                .getUserByEmail(customerEmailId);
                    }

                    if ((user == null || user.getUserId() == -1)
                            && customerMobileNumber != null
                            && !customerMobileNumber.isEmpty()) {
                        ticket.setCustomerMobileNumber(customerMobileNumber);
                        activity.setCustomerMobileNumber(customerMobileNumber);
                        user = userContextServiceClient
                                .getUserByMobileNumber(Long
                                        .parseLong(customerMobileNumber));
                    }
                } catch (UserContextException e) {
                    log.error("Could not fetch user for: " + customerEmailId
                            + " " + customerMobileNumber + " " + customerName,
                            e);
                }

                if (user != null && user.getUserId() != -1) {
                    ticket.setCustomerId(user.getUserId());
                    activity.setCustomerId(user.getUserId());
                }
            }

            // handling null values appropriately
            if (assigneeEmailId != null && !assigneeEmailId.isEmpty()) {
                long assigneeId = CRMAuthorizingRealm.getAgent(assigneeEmailId)
                        .getId();
                ticket.setAssigneeId(assigneeId);
                activity.setTicketAssigneeId(assigneeId);
            }

            crmServiceClient = new CRMClient().getClient();
            id = String
                    .valueOf(crmServiceClient.insertTicket(ticket, activity));
        } catch (TException e) {
            log.error("Error while creating ticket", e);
            return EXCEPTION;
        } catch (NumberFormatException e) {
            log.error("Error while parsing Order Id", e);
            return EXCEPTION;
        } catch (TransactionServiceException e) {
            log.error("Error while updating order status", e);
            return EXCEPTION;
        } catch (Exception e) {
            log.error(e.getMessage());
            return EXCEPTION;
        }

        return index();
    }

    public boolean isAssigneeEditable() {
        return SecurityUtils.getSubject().hasRole("TeamLead");
    }

    public String searchTickets() throws ParseException {
        try {
            SearchFilter searchFilter = new SearchFilter();
            if (userId != null && !userId.isEmpty()) {
                searchFilter.setCustomerId(Long.parseLong(userId));
            }

            if (agentIds != null && agentIds.length != 0) {
                searchFilter.setTicketAssigneeIds(new ArrayList<Long>());
                for (String agentId : agentIds) {
                    searchFilter.getTicketAssigneeIds().add(
                            CRMAuthorizingRealm.getAgent(agentId).getId());
                }
            }

            if (startTimestamp != null && !startTimestamp.isEmpty()) {
                searchFilter.setStartTimestamp(SDF.parse(startTimestamp)
                        .getTime());
            }

            if (endTimestamp != null && !endTimestamp.isEmpty()) {
                searchFilter.setEndTimestamp(SDF.parse(endTimestamp).getTime());
            }

            if (id != null && !id.isEmpty()) {
                searchFilter.setTicketId(Long.parseLong(id));
            }

            if (status != null && !status.isEmpty()) {
                searchFilter.setTicketStatuses(new ArrayList<TicketStatus>());
                searchFilter.getTicketStatuses().add(TicketStatus.valueOf(status));
                if (TicketStatus.OPEN.name().equals(status)) {
                    searchFilter.getTicketStatuses().add(TicketStatus.REOPEN);
                }
            }

            if (category != null && !category.isEmpty()) {
                searchFilter
                        .setTicketCategory(TicketCategory.valueOf(category));
            }

            crmServiceClient = new CRMClient().getClient();
            tickets = crmServiceClient.getTickets(searchFilter);
        } catch (TException e) {
            String errorString = "Error getting tickets for "
                    + currentAgentEmailId;
            log.error(errorString, e);
            addActionError(errorString);
        }

        return index();
    }

    public String getUnassignedTickets() {
        try {
            crmServiceClient = new CRMClient().getClient();
            tickets = crmServiceClient.getUnassignedTickets();
        } catch (TException e) {
            String errorString = "Error getting tickets for "
                    + currentAgentEmailId;
            log.error(errorString, e);
            addActionError(errorString);
        }

        return index();
    }

    public String update() {
        try {
            long creatorId = CRMAuthorizingRealm.getAgent(currentAgentEmailId)
                    .getId();

            SearchFilter searchFilter = new SearchFilter();
            searchFilter.setTicketId(Long.parseLong(id));
            crmServiceClient = new CRMClient().getClient();
            Ticket ticket = crmServiceClient.getTickets(searchFilter).get(0);
            ticket.setDescription(description);
            ticket.setPriority(TicketPriority.valueOf(priority));

            // Update when a ticket is closed!
            if (TicketStatus.CLOSED.name().equals(status) || TicketCategory.COD_VERIFICATION.equals(ticket.getCategory())) {
                if (TicketCategory.COD_VERIFICATION.equals(ticket.getCategory())
                        && pendingCODOrders(ticket.getCustomerId())) {
                    addActionMessage("Cod orders pending for verification. Ticket can not be closed and its category cannot be changed.");
                } else {
                    ticket.setCategory(TicketCategory.valueOf(category));
                    ticket.setStatus(TicketStatus.valueOf(status));
                    ticket.setCloseDate(new Date().getTime());
                }
            }
            else {
                ticket.setCategory(TicketCategory.valueOf(category));
                ticket.setStatus(TicketStatus.valueOf(status));
            }

            if (activityDescription == null || activityDescription.isEmpty()) {
                activityDescription = "Ticket fields updated";
            }

            Activity activity = new Activity();
            activity.setDescription(activityDescription);
            activity.setType(ActivityType.valueOf(activityType));
            activity.setTicketPriority(ticket.getPriority());
            activity.setTicketStatus(ticket.getStatus());
            activity.setCreatorId(creatorId);
            activity.setTicketCategory(ticket.getCategory());
            activity.setTicketDescription(ticket.getDescription());

            if (userId != null && !userId.isEmpty()) {
                activity.setCustomerId(Long.parseLong(userId));
            }

            // Handling null values appropriately
            if (assigneeEmailId != null && !assigneeEmailId.isEmpty()) {
                long assigneeId = CRMAuthorizingRealm.getAgent(assigneeEmailId)
                        .getId();
                ticket.setAssigneeId(assigneeId);
                activity.setTicketAssigneeId(assigneeId);
            }

            if (ActivityType.SEND_EMAIL_TO_CUSTOMER.equals(activity.getType())) {
                log.info("Sending mail");
                Client helperClient = new HelperClient().getClient();
                activity.setUserEmailId(helperClient.saveUserEmailForSending(
                        customerEmailId, CRMConstants.CRM_EMAIL_SENDOR,
                        subject, body, null, CRMConstants.CRM_EMAIL_TYPE));

                String plainTextbody = new Source(body).getTextExtractor().toString();

                // We change activityType to OTHER when pop up box for email
                // closes
                activity.setDescription("Subject: " + subject + "\n\n"
                        + "Body: " + plainTextbody);

                String activityDesc = activity.getDescription();
                if (activityDesc.length() > CRMConstants.DESCRIPTION_MAX_WIDTH) {
                    activityDesc = activityDesc.substring(0, CRMConstants.DESCRIPTION_MAX_WIDTH);
                    activityDesc += "\n\nTHIS TEXT IS TRUNCATED. PLEASE VISIT INBOX TO SEE COMPLETE DETAILS.";
                }

                activity.setDescription(activityDesc);
            }

            if (ActivityType.ESCALATE_TICKET.equals(activity.getType())) {
                log.info("Sending escalation mail");
                EscalationMatrix escalation = CRMConstants.EscalationMatrix.valueOf(escalate);
                List<Integer> escalationReceipients = escalation.getAgentIds();

                String toMailIds = "";
                for (Integer agentId : escalationReceipients) {
                    toMailIds += CRMAuthorizingRealm.getAgent(agentId).getEmailId() + ";";

                    // Setting last agent as assignee
                    ticket.setAssigneeId(agentId);
                    activity.setTicketAssigneeId(agentId);
                }

                Client helperClient = new HelperClient().getClient();
                String escalationMailSubject = createEscalationMailSubject(ticket, escalation);
                String escalationMailBody = createEscalationMailBody(ticket, escalation);

                activity.setUserEmailId(helperClient.saveUserEmailForSending(
                        toMailIds, CRMConstants.CRM_EMAIL_SENDOR,
                        escalationMailSubject, escalationMailBody,
                        null, CRMConstants.CRM_EMAIL_TYPE));

                // We change activityType to OTHER when pop up box for email
                // closes
                activity.setDescription("To: " + toMailIds + "\n\nSubject: " + escalationMailSubject + "\n\n"
                        + "Body: " + escalationMailBody);
            }

            User user = null;
            userContextServiceClient = new UserClient().getClient();
            try {
                if (customerName != null && !customerName.isEmpty()) {
                    ticket.setCustomerName(customerName);
                    activity.setCustomerName(customerName);
                }

                if (customerEmailId != null && !customerEmailId.isEmpty()) {
                    ticket.setCustomerEmailId(customerEmailId);
                    activity.setCustomerEmailId(customerEmailId);
                    user = userContextServiceClient
                            .getUserByEmail(customerEmailId);
                }

                if ((user == null || user.getUserId() == -1)
                        && customerMobileNumber != null
                        && !customerMobileNumber.isEmpty()) {
                    ticket.setCustomerMobileNumber(customerMobileNumber);
                    activity.setCustomerMobileNumber(customerMobileNumber);
                    user = userContextServiceClient.getUserByMobileNumber(Long
                            .parseLong(customerMobileNumber));
                }
            } catch (UserContextException e) {
                log.error("Could not fetch user for: " + customerEmailId + " "
                        + customerMobileNumber + " " + customerName, e);
            }

            if (user != null && user.getUserId() != -1) {
                ticket.setCustomerId(user.getUserId());
                activity.setCustomerId(user.getUserId());
            }

            crmServiceClient = new CRMClient().getClient();
            crmServiceClient.updateTicket(ticket, activity);
        } catch (TException e) {
            log.error("Error while updating ticket", e);
            return EXCEPTION;
        } catch (HelperServiceException hse) {
            log.error("Error while sending mail", hse);
            return EXCEPTION;
        }

        return index();
    }

    private String createEscalationMailBody(Ticket ticket,
            EscalationMatrix escalation)
    {
        return body + "<br />Please visit following URL to check ticket details.<br />" + 
            "http://cs.shop2020.in:8080/crm?ticketId=" + ticket.getId();
    }

    private String createEscalationMailSubject(Ticket ticket,
            EscalationMatrix escalation)
    {
        return CRMConstants.CRM_SUBJECT_PREFIX_FOR_TICKET_ID + ticket.getId() + " - ESCALATION FROM CRM - Type: " + escalation.name();
    }

    private boolean pendingCODOrders(long customerId) {
        try {
            log.info("Trying to fetch orders for " + customerId);
            transactionServiceClient = new TransactionClient().getClient();
            for (Order order : transactionServiceClient.getOrdersForCustomer(
                    customerId, 0, 0,
                    Collections.singletonList(OrderStatus.COD_VERIFICATION_PENDING))) {
                log.info("Processing order: " + order.getId() + " with COD: " + order.isCod());
                if (order.isCod()) {
                    log.info("Returning true from pendingCODOrders() for " + customerId);
                    return true;
                }
            }
        } catch (TTransportException e) {
            log.error("Error while creating thrift client", e);
        } catch (TransactionServiceException e) {
            log.error("Error fetching orders", e);
        } catch (TException e) {
            log.error("Error fetching orders", e);
        }

        log.info("Returning false from pendingCODOrders() for " + customerId);
        return false;
    }

    public String updateOrderStatus() {
        long creatorId;
        OrderStatus orderStatusEnum = null;
        try {
            creatorId = CRMAuthorizingRealm.getAgent(currentAgentEmailId).getId();
            
            if(orderStatus.equals("DENY_CANCEL_REQUEST")) {
                transactionServiceClient = new TransactionClient().getClient();
                transactionServiceClient.markOrderCancellationRequestDenied(Long.parseLong(orderId));
            } 

            else {

                orderStatusEnum = OrderStatus.valueOf(orderStatus);
                transactionServiceClient = new TransactionClient().getClient();

                if (OrderStatus.SUBMITTED_FOR_PROCESSING.equals(orderStatusEnum)) {
                    transactionServiceClient.verifyOrder(Long.parseLong(orderId));
                }
                else if (OrderStatus.COD_VERIFICATION_FAILED.equals(orderStatusEnum)) {
                    transactionServiceClient.refundOrder(Long.parseLong(orderId), currentAgentEmailId, cancelReason);
                }
                else if (OrderStatus.CANCEL_REQUEST_CONFIRMED.equals(orderStatusEnum)) {
                    transactionServiceClient.markOrderCancellationRequestConfirmed(Long.parseLong(orderId));
                }
                else {
                    throw new UnsupportedOperationException("Cannot update status of orderId: " + orderId + " to: " + orderStatus);
                }
            }
            
            SearchFilter searchFilter = new SearchFilter();
            searchFilter.setTicketId(Long.parseLong(id));
            crmServiceClient = new CRMClient().getClient();
            Ticket ticket = crmServiceClient.getTickets(searchFilter).get(0);

            // Inserting activity
            Activity activity = new Activity();
            activity.setDescription("Status updated for Order Id: " + orderId
                    + " to " + orderStatus + ", Reason: " + cancelReason + body);
            activity.setType(ActivityType.OTHER);
            activity.setTicketPriority(ticket.getPriority());
            activity.setTicketStatus(ticket.getStatus());
            activity.setCreatorId(creatorId);
            activity.setTicketCategory(ticket.getCategory());
            activity.setTicketDescription(ticket.getDescription());
            activity.setCustomerId(ticket.getCustomerId());
            activity.setTicketAssigneeId(ticket.getAssigneeId());

            crmServiceClient = new CRMClient().getClient();
            crmServiceClient.updateTicket(ticket, activity);

        } catch (TException e) {
            log.info("Thrift exception", e);
        } catch (NumberFormatException e) {
            log.info("Could not convert to long", e);
        } catch (TransactionServiceException e) {
            log.info("Transaction client exception", e);
        }

        return edit();
    }
    
    public User getUser(Long userId) {
        User user = null;

        try {
            userContextServiceClient = new UserClient().getClient();
            user = userContextServiceClient.getUserById(userId);
        } catch (UserContextException e) {
            String errorString = "Could not fetch user for " + userId;
            log.error(errorString, e);
            addActionError(errorString);
        } catch (TException e) {
            String errorString = "Could not create client";
            log.error(errorString, e);
            addActionError(errorString);
        }

        return user;
    }
    
    public String allowPayment() {
        try {
            log.info("Allowing payment for paymentId = " + paymentId);
            transactionServiceClient = new TransactionClient().getClient();
            transactionServiceClient.markTransactionAsPaymentFlagRemoved(Long.parseLong(transactionId));
            if (id != null && !id.isEmpty()) {
                SearchFilter searchFilter = new SearchFilter();
                crmServiceClient = new CRMClient().getClient();
                searchFilter.setTicketId(Long.parseLong(id));
                Ticket ticket = crmServiceClient.getTickets(searchFilter).get(0);
                // Inserting activity
                if(ticket != null) {
                    Activity activity = new Activity();
                    activity.setDescription("Flagged Payment allowed");
                    activity.setType(ActivityType.OTHER);
                    activity.setTicketPriority(ticket.getPriority());
                    activity.setTicketStatus(ticket.getStatus());
                    activity.setCreatorId(CRMAuthorizingRealm.getAgent(currentAgentEmailId).getId());
                    activity.setTicketCategory(ticket.getCategory());
                    activity.setTicketDescription(ticket.getDescription());
                    activity.setCustomerId(ticket.getCustomerId());
                    activity.setTicketAssigneeId(ticket.getAssigneeId());

                    crmServiceClient = new CRMClient().getClient();
                    crmServiceClient.updateTicket(ticket, activity);
                }
            }

        } catch (TException e) {
            log.error("Error while getting tickets", e);
            return EXCEPTION;
        } catch (NumberFormatException e) {
            log.error("Invalid ticket Id", e);
            return EXCEPTION;
        } catch (TransactionServiceException e) {
            log.error("Error while marking transactions as Flag removed", e);
            return EXCEPTION;
        }
        return edit();
    }
    
    public String blockPayment() {
        try {
            log.info("Blocking payment for paymentId = " + paymentId);
            transactionServiceClient = new TransactionClient().getClient();
            transactionServiceClient.refundTransaction(Long.parseLong(transactionId), currentAgentEmailId, "FLAGGED_PAYMENT_CANCELLED");
            if (id != null && !id.isEmpty()) {
                SearchFilter searchFilter = new SearchFilter();
                crmServiceClient = new CRMClient().getClient();
                searchFilter.setTicketId(Long.parseLong(id));
                Ticket ticket = crmServiceClient.getTickets(searchFilter).get(0);
                // Inserting activity
                if(ticket != null) {
                    Activity activity = new Activity();
                    activity.setDescription("Flagged Payment allowed");
                    activity.setType(ActivityType.OTHER);
                    activity.setTicketPriority(ticket.getPriority());
                    activity.setTicketStatus(ticket.getStatus());
                    activity.setCreatorId(CRMAuthorizingRealm.getAgent(currentAgentEmailId).getId());
                    activity.setTicketCategory(ticket.getCategory());
                    activity.setTicketDescription(ticket.getDescription());
                    activity.setCustomerId(ticket.getCustomerId());
                    activity.setTicketAssigneeId(ticket.getAssigneeId());

                    crmServiceClient = new CRMClient().getClient();
                    crmServiceClient.updateTicket(ticket, activity);
                }
            }

        } catch (TException e) {
            log.error("Error while getting tickets", e);
            return EXCEPTION;
        } catch (NumberFormatException e) {
            log.error("Invalid ticket Id", e);
            return EXCEPTION;
        } catch (TransactionServiceException e) {
            log.error("Error while allowing flagged payment", e);
            return EXCEPTION;
        }
        return edit();
    }
    
    public String authorizeReturn() {
        try {
            log.info("Authorizing OrderId =" + orderId);
            transactionServiceClient = new TransactionClient().getClient();
            transactionServiceClient.markOrderReturnRequestAuthorized(Long.parseLong(orderId), true);
            if (id != null && !id.isEmpty()) {
                SearchFilter searchFilter = new SearchFilter();
                crmServiceClient = new CRMClient().getClient();
                searchFilter.setTicketId(Long.parseLong(id));
                Ticket ticket = crmServiceClient.getTickets(searchFilter).get(0);
                // Inserting activity
                if(ticket != null) {
                    Activity activity = new Activity();
                    activity.setDescription("Return Authorized");
                    activity.setType(ActivityType.OTHER);
                    activity.setTicketPriority(ticket.getPriority());
                    activity.setTicketStatus(ticket.getStatus());
                    activity.setCreatorId(CRMAuthorizingRealm.getAgent(currentAgentEmailId).getId());
                    activity.setTicketCategory(ticket.getCategory());
                    activity.setTicketDescription(ticket.getDescription());
                    activity.setCustomerId(ticket.getCustomerId());
                    activity.setTicketAssigneeId(ticket.getAssigneeId());

                    crmServiceClient = new CRMClient().getClient();
                    crmServiceClient.updateTicket(ticket, activity);
                }
            }

        } catch (TException e) {
            log.error("Error while getting tickets", e);
            return EXCEPTION;
        } catch (NumberFormatException e) {
            log.error("Invalid ticket Id", e);
            return EXCEPTION;
        } catch (TransactionServiceException e) {
            log.error("Error while authorizing Return", e);
            return EXCEPTION;
        }
        return edit();
    }
    
    public String denyReturn() {
        try {
            log.info("Denying OrderId =" + orderId);
            transactionServiceClient = new TransactionClient().getClient();
            transactionServiceClient.markOrderReturnRequestAuthorized(Long.parseLong(orderId), false);
            if (id != null && !id.isEmpty()) {
                SearchFilter searchFilter = new SearchFilter();
                crmServiceClient = new CRMClient().getClient();
                searchFilter.setTicketId(Long.parseLong(id));
                Ticket ticket = crmServiceClient.getTickets(searchFilter).get(0);
                // Inserting activity
                if(ticket != null) {
                    Activity activity = new Activity();
                    activity.setDescription("Return Denied");
                    activity.setType(ActivityType.OTHER);
                    activity.setTicketPriority(ticket.getPriority());
                    activity.setTicketStatus(ticket.getStatus());
                    activity.setCreatorId(CRMAuthorizingRealm.getAgent(currentAgentEmailId).getId());
                    activity.setTicketCategory(ticket.getCategory());
                    activity.setTicketDescription(ticket.getDescription());
                    activity.setCustomerId(ticket.getCustomerId());
                    activity.setTicketAssigneeId(ticket.getAssigneeId());

                    crmServiceClient = new CRMClient().getClient();
                    crmServiceClient.updateTicket(ticket, activity);
                }
            }

        } catch (TException e) {
            log.error("Error while getting tickets", e);
            return EXCEPTION;
        } catch (NumberFormatException e) {
            log.error("Invalid ticket Id", e);
            return EXCEPTION;
        } catch (TransactionServiceException e) {
            log.error("Error while denying Return", e);
            return EXCEPTION;
        }
        return edit();
    }
    
    public String authorizeDOA() {
        try {
            log.info("Authorizing OrderId =" + orderId);
            transactionServiceClient = new TransactionClient().getClient();
            transactionServiceClient.markOrderDoaRequestAuthorized(Long.parseLong(orderId), true);
            if (id != null && !id.isEmpty()) {
                SearchFilter searchFilter = new SearchFilter();
                crmServiceClient = new CRMClient().getClient();
                searchFilter.setTicketId(Long.parseLong(id));
                Ticket ticket = crmServiceClient.getTickets(searchFilter).get(0);
                // Inserting activity
                if(ticket != null) {
                    Activity activity = new Activity();
                    activity.setDescription("DOA Authorized");
                    activity.setType(ActivityType.OTHER);
                    activity.setTicketPriority(ticket.getPriority());
                    activity.setTicketStatus(ticket.getStatus());
                    activity.setCreatorId(CRMAuthorizingRealm.getAgent(currentAgentEmailId).getId());
                    activity.setTicketCategory(ticket.getCategory());
                    activity.setTicketDescription(ticket.getDescription());
                    activity.setCustomerId(ticket.getCustomerId());
                    activity.setTicketAssigneeId(ticket.getAssigneeId());

                    crmServiceClient = new CRMClient().getClient();
                    crmServiceClient.updateTicket(ticket, activity);
                }
            }

        } catch (TException e) {
            log.error("Error while getting tickets", e);
            return EXCEPTION;
        } catch (NumberFormatException e) {
            log.error("Invalid ticket Id", e);
            return EXCEPTION;
        } catch (TransactionServiceException e) {
            log.error("Error while authorizing DOA", e);
            return EXCEPTION;
        }
        return edit();
    }
    
    public String denyDOA() {
        try {
            log.info("Denying OrderId =" + orderId);
            transactionServiceClient = new TransactionClient().getClient();
            transactionServiceClient.markOrderDoaRequestAuthorized(Long.parseLong(orderId), false);
            if (id != null && !id.isEmpty()) {
                SearchFilter searchFilter = new SearchFilter();
                crmServiceClient = new CRMClient().getClient();
                searchFilter.setTicketId(Long.parseLong(id));
                Ticket ticket = crmServiceClient.getTickets(searchFilter).get(0);
                // Inserting activity
                if(ticket != null) {
                    Activity activity = new Activity();
                    activity.setDescription("DOA Denied");
                    activity.setType(ActivityType.OTHER);
                    activity.setTicketPriority(ticket.getPriority());
                    activity.setTicketStatus(ticket.getStatus());
                    activity.setCreatorId(CRMAuthorizingRealm.getAgent(currentAgentEmailId).getId());
                    activity.setTicketCategory(ticket.getCategory());
                    activity.setTicketDescription(ticket.getDescription());
                    activity.setCustomerId(ticket.getCustomerId());
                    activity.setTicketAssigneeId(ticket.getAssigneeId());

                    crmServiceClient = new CRMClient().getClient();
                    crmServiceClient.updateTicket(ticket, activity);
                }
            }

        } catch (TException e) {
            log.error("Error while getting tickets", e);
            return EXCEPTION;
        } catch (NumberFormatException e) {
            log.error("Invalid ticket Id", e);
            return EXCEPTION;
        } catch (TransactionServiceException e) {
            log.error("Error while denying DOA", e);
            return EXCEPTION;
        }
        return edit();
    }

    public EscalationMatrix[] getEscalationMatrix () {
        return CRMConstants.EscalationMatrix.values();
    }

    public String getAddress(Order order) {
        return ModelUtils.extractAddressFromOrder(order);
    }

    public String getProductName(LineItem lineItem) {
        return ModelUtils.extractProductNameFromLineItem(lineItem) + " " + lineItem.getColor();
    }

    public ActivityType[] getActivityTypes() {
        return ActivityType.values();
    }

    public TicketStatus[] getTicketStatuses() {
        return TicketStatus.values();
    }

    public Agent getAgent(long agentId) throws TException {
        return CRMAuthorizingRealm.getAgent(agentId);
    }

    public List<Agent> getAllAgents() {
        return CRMAuthorizingRealm.getAgents();
    }

    public TicketCategory[] getTicketCategories() {
        return TicketCategory.values();
    }

    public TicketPriority[] getTicketPriorities() {
        return TicketPriority.values();
    }

    public List<Ticket> getTickets() {
        return tickets;
    }

    public void setTickets(List<Ticket> tickets) {
        this.tickets = tickets;
    }

    public String getCustomerEmailId() {
        return customerEmailId;
    }

    public void setCustomerEmailId(String customerEmailId) {
        this.customerEmailId = customerEmailId;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getAssigneeEmailId() {
        return assigneeEmailId;
    }

    public void setAssigneeEmailId(String assigneeEmailId) {
        this.assigneeEmailId = assigneeEmailId;
    }

    public String getPriority() {
        return priority;
    }

    public void setPriority(String priority) {
        this.priority = priority;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public String[] getAgentIds() {
        return agentIds;
    }

    public void setAgentIds(String[] agentIds) {
        this.agentIds = agentIds;
    }

    public String getStartTimestamp() {
        return startTimestamp;
    }

    public void setStartTimestamp(String startTimestamp) {
        this.startTimestamp = startTimestamp;
    }

    public String getEndTimestamp() {
        return endTimestamp;
    }

    public void setEndTimestamp(String endTimestamp) {
        this.endTimestamp = endTimestamp;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getActivityDescription() {
        return activityDescription;
    }

    public void setActivityDescription(String activityDescription) {
        this.activityDescription = activityDescription;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getActivityType() {
        return activityType;
    }

    public void setActivityType(String activityType) {
        this.activityType = activityType;
    }

    public Ticket getTicket() {
        return ticket;
    }

    public void setTicket(Ticket ticket) {
        this.ticket = ticket;
    }

    public List<Activity> getActivities() {
        return activities;
    }

    public void setActivities(List<Activity> activities) {
        this.activities = activities;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getCustomerMobileNumber() {
        return customerMobileNumber;
    }

    public void setCustomerMobileNumber(String customerMobileNumber) {
        this.customerMobileNumber = customerMobileNumber;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getOrderStatus() {
        return orderStatus;
    }

    public void setOrderStatus(String orderStatus) {
        this.orderStatus = orderStatus;
    }

    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }

    public String getEscalate() {
        return escalate;
    }

    public void setEscalate(String escalate) {
        this.escalate = escalate;
    }

    public String getCancelReason() {
        return cancelReason;
    }

    public void setCancelReason(String cancelReason) {
        this.cancelReason = cancelReason;
    }

    public List<Payment> getPayments() {
        return payments;
    }

    public void setPayments(List<Payment> payments) {
        this.payments = payments;
    }

    public String getTransactionId() {
        return transactionId;
    }

    public void setTransactionId(String transactionId) {
        this.transactionId = transactionId;
    }

    public String getPaymentId() {
        return paymentId;
    }

    public void setPaymentId(String paymentId) {
        this.paymentId = paymentId;
    }

    public HashMap<String, String> getAllAttachmentsForTicket() {
        return allAttachmentsForTicket;
    }

    public void setAllAttachmentsForTicket(HashMap<String, String> allAttachmentsForTicket) {
        this.allAttachmentsForTicket = allAttachmentsForTicket;
    }
}