mvc.OrderController.java Source code

Java tutorial

Introduction

Here is the source code for mvc.OrderController.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mvc;

import datastructure.AuthorMessageData;
import datastructure.OrderListData;
import datastructure.OrderSearchData;
import entity.Admin;
import entity.AdminMessage;
import entity.Author;
import entity.AuthorMessage;
import entity.Branch;
import entity.DelegateMessage;
import entity.Direction;
import entity.EmailNotice;
import entity.Order;
import entity.OrderFile;
import entity.OrderLog;
import entity.OrderType;
import entity.Payment;
import entity.PaymentType;
import entity.ReadyOrderFile;
import entity.SmsNotice;
import entity.User;
import entity.orderStatus.OrderStatus;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import mvc.parent.WebController;
import mvc.result.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import rights.NotRightException;
import service.AuthorService;
import service.BranchService;
import service.DirectionService;
import service.OrderTypeService;
import service.PaymentService;
import service.PaymentTypeService;
import support.Converter;
import support.ServiceResult;

import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import javax.servlet.http.HttpServletRequest;
import mvc.formObjects.ReportFormData;
import mvc.support.LogObject;
import mvc.view.OrderCssManager;
import mvc.view.ViewResolver;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import rights.BranchRights;
import rights.Rights;
import rights.UserRightsUtil;
import service.AuthorSalaryService;
import service.DelegateMessageService;
import service.MessageService;
import service.NoticeService;
import service.OrderLogService;
import service.OrderViewService;
import support.DateFormatter;
import support.ErrorMess;
import support.FormatDate;
import support.StringAdapter;

/**
 *
 * @author Rice Pavel
 */
@Controller
@RequestMapping("Order")
public class OrderController extends WebController {

    @Autowired
    private NoticeService noticeService;

    @Autowired
    private OrderTypeService orderTypeService;

    @Autowired
    private BranchService branchService;

    @Autowired
    private DirectionService directionService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private PaymentTypeService paymentTypeService;

    @Autowired
    private AuthorService authorService;

    @Autowired
    private MessageService messageService;

    @Autowired
    private DelegateMessageService delegateMessageService;

    @Autowired
    private OrderLogService orderLogService;

    @Autowired
    private OrderViewService orderViewService;

    @Autowired
    private AuthorSalaryService authorSalaryService;

    private final static String TYPE_EMAIL = "email";

    private final static String TYPE_PHONE = "phone";

    public static String getUrlForOrderSearch() {
        return "/Order/search";
    }

    @RequestMapping("/getMenu")
    public String getMenu(Map<String, Object> model,
            @RequestParam(value = "authorId", required = false) Long authorId) {
        setOrderInfoForMenu(model, authorId);
        return "orderMenu";
    }

    @RequestMapping("/getDataForMenu")
    @ResponseBody
    public Map<String, Object> getDataForMenu(@RequestParam(value = "authorId", required = false) Long authorId,
            @RequestParam(value = "branchId", required = false) Long branchId) {
        List<OrderStatus> rightStatusList = getRightsStatusList();
        datastructure.CountOrders countOrders = orderService.getCountOrders(authorId, branchId, rightStatusList);
        Map<String, Object> resultMap = new LinkedHashMap();
        resultMap.put("ALL", countOrders.getCountAll());
        for (OrderStatus status : countOrders.counts.keySet()) {
            resultMap.put(status.toString(), countOrders.counts.get(status));
        }
        resultMap.put("haveCost", countOrders.countHaveCost);
        return resultMap;
    }

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String add(Map<String, Object> model, String submit, @ModelAttribute("order") Order order,
            BindingResult result, RedirectAttributes ra) throws IOException {
        setInfoForCommonPage(model);
        return _add(model, submit, order, result, null, ra);
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String add(Map<String, Object> model, String submit, @ModelAttribute("order") Order order,
            BindingResult result, @RequestParam(value = "file", required = false) MultipartFile[] files,
            RedirectAttributes ra) throws IOException, NotRightException {
        setInfoForCommonPage(model);
        checkBranchRight(order, "/Order/add");
        return _add(model, submit, order, result, files, ra);
    }

    @RequestMapping("addByajax")
    public String add(Map<String, Object> model,
            @RequestParam(value = "orderTypeId", required = false) Long orderTypeId,
            @RequestParam(value = "subject", required = false) String subject,
            @RequestParam(value = "deadlineDate", required = false) Date realDate,
            @RequestParam(value = "directions", required = false) List<Long> directionIds,
            @RequestParam(value = "clientFio", required = false) String clientFio,
            @RequestParam(value = "clientPhone", required = false) String clientPhone,
            @RequestParam(value = "clientEmail", required = false) String clientEmail,
            @RequestParam(value = "city", required = false) String city,
            @RequestParam(value = "comment", required = false) String comment,
            @RequestParam(value = "siteName", required = false) String siteName, HttpServletResponse response,
            @RequestParam(value = "callback", required = false) String callback,
            @RequestParam(value = "files", required = false) MultipartFile[] files) throws IOException {
        try {
            ServiceResult result = new ServiceResult();
            Long id = orderService.addOrder(orderTypeId, subject, realDate, directionIds, clientFio, clientPhone,
                    clientEmail, city, comment, siteName, files, result);
            String error = "";
            if (result.hasErrors()) {
                error += result.getErrors().toString();
            }
            setModelParameter(model, "error", error);
            model.put("orderId", id);
        } catch (Exception e) {
            setModelParameter(model, "error", e.getMessage());
        }
        return "Order_addToIframe";
    }

    @RequestMapping(value = "addFile", method = RequestMethod.POST)
    public String addFile(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam(value = "file", required = false) MultipartFile[] files)
            throws IOException, NotRightException {
        _addFiles(model, orderId, files);
        return "redirect:/Order/get?orderId=" + orderId;
    }

    @RequestMapping(value = "addReadyFile", method = RequestMethod.POST)
    public String addReadyFile(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam(value = "file", required = false) MultipartFile[] files) throws Exception {
        Order obj = orderService.find(orderId);
        checkBranchRight(obj, "/Order/addReadyFile");
        for (MultipartFile file : files) {
            orderService.addReadyFile(obj, file);
        }
        return "redirect:/Order/get?orderId=" + orderId;
    }

    @RequestMapping("/change")
    public String change(Map<String, Object> model, String submit, @ModelAttribute("order") Order order,
            BindingResult bindRes, @RequestParam("orderId") Long id) throws NotRightException {
        setInfoForCommonPage(model);
        checkBranchRight(id, "/Order/change");

        // ? ?
        setComboLists(model);
        if (submit != null && !submit.isEmpty()) {
            if (!bindRes.hasErrors()) {
                ServiceResult res = orderService.update(order);
                addErrorsToModel(model, res);
                if (!res.hasErrors()) {
                    return "redirect:/Order/search";
                }
            }
        } else {
            order = orderService.find(id);
        }
        model.put("order", order);
        return "Order_change";
    }

    /**
     *   
     *
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/change", params = { "changeFirstFlag" })
    @ResponseBody
    public Map<String, Object> changeFirstFlag(@RequestParam("orderId") Long orderId) {
        orderService.changeFirstFlag(orderId);
        return new HashMap<String, Object>();
    }

    /**
     *   
     *
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/change", params = { "changeSecondFlag" })
    @ResponseBody
    public Map<String, Object> changeSecondFlag(@RequestParam("orderId") Long orderId) {
        orderService.changeSecondFlag(orderId);
        return new HashMap<String, Object>();
    }

    /**
     *    ajax
     *
     * @param value - ,   
     * @param parameterName -  
     * @param orderId -  
     * @param fromTable -     
     * @return map,   ? ? newName ( ,
     *    ), newValue ( , 
     *  ?  ), error - , ? ?.
     */
    @RequestMapping(value = "/change", params = { "ajax" })
    @ResponseBody
    public Map<String, Object> changeByAjax(@RequestParam(value = "value", required = false) String value,
            @RequestParam("parameterName") String parameterName, @RequestParam("orderId") Long orderId,
            @RequestParam(value = "fromTable", required = false) String fromTable) {
        try {
            ServiceResult serviceRes = new ServiceResult();
            String newValue = "";
            String newName = "";
            //  
            //   ?  ?   
            //   ? ? id
            Order order = orderService.find(orderId);
            //  ? 
            if (parameterName.equals("subject")) {
                order.setSubject(value);
            } else if (parameterName.equals("deadlineDate")) {
                Date date = Converter.getDate(value);
                order.setDeadlineDate(date);
            } else if (parameterName.equals("realDate")) {
                Date date = Converter.getDate(value);
                order.setRealDate(date);
            } else if (parameterName.equals("orderType")) {
                OrderType type = orderTypeService.getOne(value);
                order.setOrderType(type);
            } else if (parameterName.equals("clientFio")) {
                order.setClientFio(value);
            } else if (parameterName.equals("clientPhone")) {
                order.setClientPhone(value);
            } else if (parameterName.equals("clientEmail")) {
                order.setClientEmail(value);
            } else if (parameterName.equals("city")) {
                order.setCity(value);
            } else if (parameterName.equals("comment")) {
                order.setComment(value);
            } else if (parameterName.equals("authorComment")) {
                order.setAuthorComment(value);
            } else if (parameterName.equals("firstFlag")) {
                Boolean flag = Boolean.parseBoolean(value);
                order.setFirstFlag(flag);
            } else if (parameterName.equals("secondFlag")) {
                Boolean flag = Boolean.parseBoolean(value);
                order.setSecondFlag(flag);
            } else if (parameterName.equals("numberOfPages")) {
                order.setNumberOfPages(value);
            } else if (parameterName.equals("authorSubject")) {
                order.setAuthorSubject(value);
            } else {
                serviceRes.addError("    ??");
            }
            if (!serviceRes.hasErrors()) {
                serviceRes = orderService.update(order);
                orderService.refresh(order);
                // ?  
                if (!serviceRes.hasErrors()) {
                    if (parameterName.equals("subject")) {
                        newValue = order.getSubject();
                        newName = newValue;
                    } else if (parameterName.equals("deadlineDate")) {
                        DateFormatter formatter = new DateFormatter();
                        newValue = formatter.date(order.getDeadlineDate());
                        if (fromTable != null && fromTable.equals("true")) {
                            newName = formatter.format(order.getDeadlineDate(), "dd/MM");
                        } else {
                            newName = newValue;
                        }
                    } else if (parameterName.equals("realDate")) {
                        DateFormatter formatter = new DateFormatter();
                        newValue = formatter.date(order.getRealDate());
                        if (fromTable != null && fromTable.equals("true")) {
                            newName = formatter.format(order.getRealDate(), "dd/MM");
                        } else {
                            newName = newValue;
                        }
                    } else if (parameterName.equals("orderType")) {
                        OrderType type = order.getOrderType();
                        if (type != null) {
                            newValue = type.getOrderTypeId().toString();
                            newName = type.getName();
                        }
                    } else if (parameterName.equals("clientFio")) {
                        newValue = order.getClientFio();
                        newName = newValue;
                    } else if (parameterName.equals("clientPhone")) {
                        newValue = order.getClientPhone();
                        newName = newValue;
                    } else if (parameterName.equals("clientEmail")) {
                        newValue = order.getClientEmail();
                        newName = newValue;
                    } else if (parameterName.equals("city")) {
                        newValue = order.getCity();
                        newName = newValue;
                    } else if (parameterName.equals("comment")) {
                        newValue = order.getComment();
                        newName = newValue;
                    } else if (parameterName.equals("authorComment")) {
                        newValue = order.getAuthorComment();
                        newName = newValue;
                    } else if (parameterName.equals("firstFlag")) {
                        newValue = order.getFirstFlag().toString();
                        newName = newValue;
                    } else if (parameterName.equals("secondFlag")) {
                        newValue = order.getSecondFlag().toString();
                        newName = newValue;
                    } else if (parameterName.equals("numberOfPages")) {
                        newValue = order.getNumberOfPages();
                        newName = newValue;
                    } else if (parameterName.equals("authorSubject")) {
                        newValue = order.getAuthorSubject();
                        newName = newValue;
                    } else {
                        serviceRes.addError(
                                "    ??");
                    }
                }
            }

            Map<String, Object> resultMap = new HashMap();
            String error = "";
            if (serviceRes.hasErrors()) {
                error += serviceRes.getErrors().toString();
            }
            resultMap.put("error", error);
            resultMap.put("newValue", newValue);
            resultMap.put("newName", newName);
            return resultMap;
        } catch (Throwable exc) {
            Map<String, Object> resultMap = new HashMap();
            resultMap.put("error", StringAdapter.getStackExeption(exc));
            return resultMap;
        }
    }

    /**
     *   
     *
     * @param model 
     * @param orderId  
     * @param salaryStr  
     * @param commentToAuthorSalary    
     * @return
     */
    @RequestMapping("/changeAuthorSalary")
    @ResponseBody
    public AjaxResult changeSalary(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam("salary") String salaryStr,
            @RequestParam(value = "commentToAuthorsalary", required = false) String commentToAuthorSalary) {

        try {
            checkBranchRight(orderId, "/Order/changeAuthorSalary");
        } catch (NotRightException e) {
            return new AjaxResult("? ");
        }

        Double salary = null;
        try {
            salary = Double.valueOf(salaryStr);
        } catch (Exception e) {
        }
        ServiceResult res = orderService.changeSalary(orderId, salary, commentToAuthorSalary);
        AjaxResult ajaxRes = getAjaxResult(res);
        Order order = orderService.find(orderId);
        //ajaxRes.setValue(order.getAuthor_salary());
        Map<String, Object> resultMap = new HashMap();
        resultMap.put("authorSalary", order.getAuthor_salary());
        resultMap.put("commentToAuthorSalary", order.getCommentToAuthorSalary());
        ajaxRes.setValue(resultMap);
        return ajaxRes;
    }

    /**
     *  ??
     *
     * @param model
     * @param orderId
     * @param costStr
     * @return
     */
    @RequestMapping("/changeCost")
    @ResponseBody
    public AjaxResult changeCost(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam("cost") String costStr) {

        try {
            checkBranchRight(orderId, "/Order/changeCost");
        } catch (NotRightException e) {
            return new AjaxResult("? ");
        }

        Double cost = null;
        try {
            cost = Double.valueOf(costStr);
        } catch (Exception e) {
        }
        if (cost != null) {
            ServiceResult res = orderService.changeCost(orderId, cost);
            AjaxResult ajaxRes = getAjaxResult(res);
            Order order = orderService.find(orderId);
            ajaxRes.setValue(order.getCost());
            return ajaxRes;
        } else {
            return new AjaxResult("   ?!");
        }
    }

    @RequestMapping("/changeBranch")
    @ResponseBody
    public AjaxResult changeBranch(Map<String, Object> map, @RequestParam("orderId") Long orderId,
            @RequestParam(value = "branchId", required = false) Long branchId) {
        orderService.changeBranch(orderId, branchId);
        return new AjaxResult();
    }

    /**
     *    
     *
     * @param model
     * @param orderId
     * @param branchId
     * @return
     * @throws Exception
     */
    @RequestMapping("/delegate")
    @ResponseBody
    public Map<String, Object> delegate(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam("branchId") Long branchId) throws Exception {
        Map<String, Object> resultMap = new LinkedHashMap();
        orderService.delegate(orderId, branchId);
        resultMap.put("branchId", branchId);
        return resultMap;
    }

    @RequestMapping("/statistics")
    public String getStatistics(Map<String, Object> model,
            @RequestParam(value = "dateFrom", required = false) Date dateFrom,
            @RequestParam(value = "dateTo", required = false) Date dateTo,
            @RequestParam(value = "branchId", required = false) Long branchId) {
        if (dateFrom == null) {
            dateFrom = new Date();
        }
        if (dateTo == null) {
            dateTo = new Date();
        }
        dateFrom = support.DateUtils.startOfDay(dateFrom);
        dateTo = support.DateUtils.startOfDay(dateTo);

        setInfoForCommonPage(model);
        setComboInfoForStatistics(model);

        //  ?? 
        dateFrom = getStatisticsStartDate(dateFrom);
        dateTo = getStatisticsEndDate(dateTo);
        model.put("dateFrom", dateFrom);
        model.put("dateTo", dateTo);
        //   ?
        Set<Long> branchIds = branchRightsHolder.getBranchIds(BranchRights.SEARCH_ORDER);
        List<Map> orderList = orderService.getStatistics(dateFrom, dateTo, branchId, branchIds);
        List<Map> listByMonth = orderService.getStatisticsByDates(dateFrom, dateTo, branchId, branchIds);
        setModelParameter(model, "orderList", orderList);
        model.put("count", orderList.size());
        model.put("totalAmount", getTotalAmount(orderList));
        model.put("totalAuthorSalary", getTotalAuthorSalary(orderList));
        model.put("totalProfit", getTotalProfit(orderList));
        setModelParameter(model, "json", getJsonStringByDateList(dateFrom, dateTo, listByMonth));
        //  ? json  
        return "Order_statistics";
    }

    private void setComboInfoForStatistics(Map<String, Object> model) {
        List<Branch> branchList = branchService.getAll();
        setModelParameter(model, "branchList", branchList);
    }

    private Date getStatisticsStartDate(Date dateFrom) {
        if (dateFrom != null) {
            return dateFrom;
        } else {
            Calendar cl = Calendar.getInstance();
            cl.set(Calendar.DAY_OF_MONTH, 1);
            cl.set(Calendar.HOUR_OF_DAY, 0);
            cl.set(Calendar.MINUTE, 0);
            return cl.getTime();
        }
    }

    private double getTotalAmount(List<Map> orderList) {
        double amount = 0;
        for (Map map : orderList) {
            if (map.get("amount_sum") != null) {
                amount += (double) map.get("amount_sum");
            }

        }
        return amount;
    }

    private double getTotalAuthorSalary(List<Map> orderList) {
        double salary = 0;
        for (Map map : orderList) {
            if (map.get("author_salary") != null) {
                salary += (double) map.get("author_salary");
            }
        }
        return salary;
    }

    private double getTotalProfit(List<Map> orderList) {
        double profit = 0;
        for (Map map : orderList) {
            if (map.get("profit") != null) {
                profit += (double) map.get("profit");
            }
        }
        return profit;
    }

    private String getJsonStringByDateList(Date dateFrom, Date dateTo, List<Map> listByDates) {
        String json = "";

        Calendar cl = Calendar.getInstance();
        cl.setTime(dateFrom);
        setStartOfDay(cl);
        Calendar end = Calendar.getInstance();
        end.setTime(dateTo);
        setStartOfDay(end);
        // ?  ?
        for (; cl.before(end) || cl.equals(end); cl.add(Calendar.DAY_OF_MONTH, 1)) {
            int year = cl.get(Calendar.YEAR);
            int month = cl.get(Calendar.MONTH) + 1;
            int day = cl.get(Calendar.DAY_OF_MONTH);
            json += getJsonByDate(listByDates, day, month, year);
        }
        return json;
    }

    private String getJsonByDate(List<Map> listByDates, int day, int month, int year) {
        //  ?  
        // ? ? ?
        // 
        // ? 
        //  
        int javascriptMonth = month - 1;
        Double[] arr = getParamsByDate(listByDates, day, month, year);
        if (arr != null) {
            Double amountSum = arr[0];
            Double authorSalary = arr[1];
            Double profit = arr[2];
            return "[new Date(" + year + ", " + javascriptMonth + ", " + day + "), " + amountSum + ",  "
                    + authorSalary + ", " + profit + "],";
        }
        return "[new Date(" + year + ", " + javascriptMonth + ", " + day + "), 0, 0, 0],";
    }

    private Double[] getParamsByDate(List<Map> listByDates, int day, int month, int year) {
        for (Map map : listByDates) {
            int monthFromMap;
            try {
                monthFromMap = (int) map.get("month");
            } catch (Exception e) {
                monthFromMap = ((BigInteger) map.get("month")).intValue();
            }
            int dayFromMap;
            try {
                dayFromMap = (int) map.get("day");
            } catch (Exception e) {
                dayFromMap = ((BigInteger) map.get("day")).intValue();
            }
            int yearFromMap;
            try {
                yearFromMap = (int) map.get("year");
            } catch (Exception e) {
                yearFromMap = ((BigInteger) map.get("year")).intValue();
            }
            Double amountSum = (map.get("amount_sum") != null ? (Double) map.get("amount_sum") : 0);
            Double authorSalary = (map.get("author_salary") != null ? (Double) map.get("author_salary") : 0);
            Double profit = (map.get("profit") != null ? (Double) map.get("profit") : 0);

            if (month == monthFromMap && day == dayFromMap && year == yearFromMap) {
                return new Double[] { amountSum, authorSalary, profit };
            }
        }
        return null;
    }

    /*
     private String getByDate(Calendar cl, List<Map> listByDates) {
     //  ?  
     // ? ? ?
     // 
     // ? 
     //  
     Double[] arr = getParamsByDate(cl, listByDates);
     int year = cl.get(Calendar.YEAR);
     int month = cl.get(Calendar.MONTH) + 1;
     int day = cl.get(Calendar.DAY_OF_MONTH);
     if (arr != null) {
     Double amountSum = arr[0];
     Double authorSalary = arr[1];
     Double profit = arr[2];
     return "[new Date(" + year + ", " + month + ", " + day + "), " + amountSum + ",  " + authorSalary + ", " + profit + "],";
     }
     return "[new Date(" + year + ", " + month + ", " + day + "), 0, 0, 0],";
     }
        
     private Double[] getParamsByDate(Calendar cl, List<Map> listByDates) {
     for (Map map : listByDates) {
     int month = (int) map.get("month");
     int day = (int) map.get("day");
     int year = (int) map.get("year");
     Double amountSum = (map.get("amount_sum") != null ? (Double) map.get("amount_sum") : 0);
     Double authorSalary = (map.get("author_salary") != null ? (Double) map.get("author_salary") : 0);
     Double profit = (map.get("profit") != null ? (Double) map.get("profit") : 0);
        
     int clMonth = (cl.get(Calendar.MONTH));
     int clDay = cl.get(Calendar.DAY_OF_MONTH);
     int clYear = cl.get(Calendar.YEAR);
     if (month == clMonth
     && day == clDay
     && year == clYear) {
     return new Double[]{amountSum, authorSalary, profit};
     }
     }
     return null;
     }
     */
    private void setStartOfDay(Calendar cl) {
        cl.set(Calendar.HOUR_OF_DAY, 0);
        cl.set(Calendar.MINUTE, 0);
        cl.set(Calendar.SECOND, 0);
        cl.set(Calendar.MILLISECOND, 0);
    }

    private Date getStatisticsEndDate(Date dateTo) {
        if (dateTo != null) {
            return dateTo;
        } else {
            Calendar cl = Calendar.getInstance();
            cl.set(Calendar.DAY_OF_MONTH, cl.getActualMaximum(Calendar.DAY_OF_MONTH));
            cl.set(Calendar.HOUR_OF_DAY, 23);
            cl.set(Calendar.MINUTE, 59);
            return cl.getTime();
        }
    }

    @RequestMapping("/changeDirections")
    @ResponseBody
    public Map<String, Object> replaceDirections(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam(value = "oldDirectionId", required = false) Long oldDirectionId,
            @RequestParam(value = "newDirectionId", required = false) Long newDirectionId) {
        final String addedStatus = "added";
        final String deletedStatus = "deleted";
        final String notChangedStatus = "notChanged";
        String status = "";
        try {
            Order order = orderService.find(orderId);
            Long branchId = (order != null && order.getBranch() != null ? order.getBranch().getBranchId() : null);
            if (branchRightsHolder.isRight(BranchRights.ORDER_CHANGE_STATUS, branchId)) {
                boolean deleted = false;
                boolean added = false;
                // ?  ? 
                if (oldDirectionId != null) {
                    //  ? 
                    orderService.deleteDirection(orderId, oldDirectionId);
                    deleted = true;
                }
                // ?   
                if (newDirectionId != null) {
                    //   
                    orderService.addDirection(orderId, newDirectionId);
                    added = true;
                }
                if (added) {
                    status = addedStatus;
                } else if (deleted) {
                    status = deletedStatus;
                } else {
                    status = notChangedStatus;
                }
            } else {
                status = notChangedStatus;
            }
        } catch (Exception e) {
            status = notChangedStatus;
        }
        Map<String, Object> map = new HashMap();
        map.put("status", status);
        return map;

    }

    /*
     @RequestMapping("/changeStatus")
     @ResponseBody
     public AjaxResult changeStatus(Map<String, Object> model, @RequestParam("orderId") Long orderId,
     @RequestParam("status") String status) throws NotRightException {
     checkBranchRight(orderId, "/Order/changeStatus");
     ServiceResult res = orderService.changeStatus(orderId, status);
     AjaxResult ar = new AjaxResult();
     if (res.hasErrors()) {
     ar.setError(res.getErrors().toString());
     } else {
     try {
     OrderStatus st = OrderStatus.valueOf(status);
     ar.setValue(st.getName());
     } catch (Exception e) {
        
     }
     }
     return ar;
     }
     */
    @RequestMapping("/changeStatus")
    @ResponseBody
    public Map<String, Object> changeStatus(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam("status") String status) throws NotRightException {

        checkBranchRight(orderId, "/Order/changeStatus");
        String error = "";
        if (authManager.getCurrentUser() instanceof Admin) {

            ServiceResult res = orderService.changeStatus(orderId, status);
            if (res.hasErrors()) {
                error = res.getErrors().toString();
            }
        }
        Order order = orderService.find(orderId);
        Map<String, Object> resultMap = new HashMap();

        String cssClass = "none";
        String statusName = getStatusName(order);

        try {
            OrderStatus st = OrderStatus.valueOf(status);
            cssClass = new OrderCssManager(authManager.getCurrentUser()).getStatusClass(order,
                    order.getPaymentSum());
        } catch (Exception e) {

        }

        resultMap.put("error", error);
        resultMap.put("value", statusName);
        resultMap.put("cssClass", cssClass);
        return resultMap;
    }

    private String getStatusName(Order order) {
        boolean existReject = orderService.existRejectForAuthUser(order);
        return new ViewResolver(authManager.getCurrentUser(), branchRightsHolder).getStatusName(order.getStatus(),
                existReject, order.getCost(), order.getStatusOfUser());
    }

    @RequestMapping("contacts")
    public String contacts(Map<String, Object> model,
            @RequestParam(value = "branchId", required = false) Set<Long> brancheIds,
            @RequestParam(value = "orderTypeId", required = false) Set<Long> orderTypeIds,
            @RequestParam(value = "directionId", required = false) Set<Long> directionIds,
            @RequestParam(value = "from", required = false) Date from,
            @RequestParam(value = "to", required = false) Date to,
            @RequestParam(value = "type", required = false) String type) {
        setInfoForCommonPage(model);
        setInfoForSearch(model);

        Set<Long> rightBranchIds = getBranchIdsForContacts();

        if (from == null) {
            from = getStartMonth();
        }
        if (to == null) {
            to = getEndMonth();
        }
        if (type == null) {
            type = TYPE_EMAIL;
        }
        setModelParameter(model, "from", standartFormatDate(from));
        setModelParameter(model, "to", standartFormatDate(to));
        setModelParameter(model, "type", type);

        ReportFormData data = new ReportFormData();
        data.brancheIds = brancheIds;
        data.directionIds = directionIds;
        data.orderTypeIds = orderTypeIds;
        data.from = from;
        data.to = to;

        Set<String> set = getPhonesOrEmails(rightBranchIds, data, type);
        String str = "";
        for (String value : set) {
            str += value + ", ";
        }
        setModelParameter(model, "str", str);
        return "Order_contacts";
    }

    @RequestMapping("contactsExcel")
    public void contactsExcel(HttpServletResponse response,
            @RequestParam(value = "branchId", required = false) Set<Long> brancheIds,
            @RequestParam(value = "orderTypeId", required = false) Set<Long> orderTypeIds,
            @RequestParam(value = "directionId", required = false) Set<Long> directionIds,
            @RequestParam(value = "from", required = false) Date from,
            @RequestParam(value = "to", required = false) Date to,
            @RequestParam(value = "type", required = false) String type) throws IOException {
        Set<Long> rightBranchIds = getBranchIdsForContacts();

        ReportFormData data = new ReportFormData();
        data.brancheIds = brancheIds;
        data.orderTypeIds = orderTypeIds;
        data.directionIds = directionIds;
        data.from = from;
        data.to = to;

        getXls(response, rightBranchIds, data, type);
    }

    @RequestMapping("contactsTxt")
    public void contactsTxt(HttpServletResponse response,
            @RequestParam(value = "branchId", required = false) Set<Long> brancheIds,
            @RequestParam(value = "orderTypeId", required = false) Set<Long> orderTypeIds,
            @RequestParam(value = "directionId", required = false) Set<Long> directionIds,
            @RequestParam(value = "from", required = false) Date from,
            @RequestParam(value = "to", required = false) Date to,
            @RequestParam(value = "type", required = false) String type) throws IOException {

        Set<Long> rightBranchIds = getBranchIdsForContacts();

        ReportFormData data = new ReportFormData();
        data.brancheIds = brancheIds;
        data.orderTypeIds = orderTypeIds;
        data.directionIds = directionIds;
        data.from = from;
        data.to = to;

        Set<String> set = getPhonesOrEmails(rightBranchIds, data, type);
        String str = "";
        for (String value : set) {
            str += value + "\r\n";
        }
        String fileName = "contacts.txt";
        if (type.equals(TYPE_PHONE)) {
            fileName = "phones.txt";
        } else if (type.equals(TYPE_EMAIL)) {
            fileName = "emails.txt";
        }
        byte[] bytes = str.getBytes("UTF-8");
        _getFile(response, fileName, bytes);
    }

    @RequestMapping("/delete")
    public String delete(Map<String, Object> model, String submit, @RequestParam("orderId") Long id,
            RedirectAttributes ra) throws NotRightException {
        // ? ?
        try {
            Order obj = orderService.find(id);
            checkBranchRight(obj, "/Order/delete");

            orderService.delete(obj);
        } catch (DataIntegrityViolationException e) {
            addErrorToRedirecrt(ra, ErrorMess.EXIST_RELATED_ENTITY);
        }
        return "redirect:/Order/search";
    }

    @RequestMapping("delFile")
    public String delFile(Map<String, Object> model, @RequestParam("fileId") Long fileId,
            @RequestParam("orderId") Long orderId) throws NotRightException {
        setInfoForCommonPage(model);
        checkRightsByOrderFileId(fileId, "/Order/delFile");
        _deleteFile(fileId);
        return "redirect:/Order/get?orderId=" + orderId;
    }

    @RequestMapping("delReadyFile")
    public String delReadyFile(Map<String, Object> model, @RequestParam("fileId") Long readyFileId,
            @RequestParam("orderId") Long orderId) throws NotRightException {
        setInfoForCommonPage(model);
        checkRightsByReadyFileId(readyFileId, "/Order/delReadyFile");
        _deleteFile(readyFileId);
        return "redirect:/Order/get?orderId=" + orderId;
    }

    @RequestMapping("/detailReport")
    public String getDetailReport(Map<String, Object> model,
            @RequestParam(value = "from", required = false) String from,
            @RequestParam(value = "to", required = false) String to, @RequestParam("orderId") Long orderId) {
        setInfoForCommonPage(model);
        Date dateFrom = null;
        Date dateTo = null;
        if (from != null && to != null) {
            dateFrom = Converter.getDate(from);
            dateTo = Converter.getDate(to);
        }
        if (to != null && from != null) {
            setModelParameter(model, "list", orderService.getDetailReport(dateFrom, dateTo, orderId));
        } else {
            setModelParameter(model, "error",
                    "       ");
        }
        return "Order_detail_report";
    }

    /**
     * ?  
     *
     * @param model
     * @param orderId
     * @param ajax
     * @param request
     * @return
     * @throws NotRightException
     */
    @RequestMapping("/get")
    public String showOne(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam(value = "ajax", required = false) String ajax, HttpServletRequest request)
            throws NotRightException {
        long starttime = System.currentTimeMillis();
        //log.warn("OrderLog ");

        Order order = orderService.find(orderId);

        //log.warn("1 " + Long.valueOf(System.currentTimeMillis() - starttime));

        List<Long> toWork = branchRightsHolder.getBranches(BranchRights.ORDER_NEW_TO_WORK);
        List<Long> toReject = branchRightsHolder.getBranches(BranchRights.ORDER_NEW_TO_REJECT);
        setModelParameter(model, "possibleStatusList",
                getPossibleStatuses(order, getRightOrderStatus(), toWork, toReject));
        checkBranchRight(order, "/Order/get");
        readyMessages(order, request);
        saveOrderView(order);

        //log.warn("2 " + Long.valueOf(System.currentTimeMillis() - starttime));

        model.put("order", order);
        setInfoForOrder(model, orderId, order);
        setAuthorMessages(model, order);

        //log.warn("3 " + Long.valueOf(System.currentTimeMillis() - starttime));

        setInfoForPayment(model, orderId);
        setInfoForMessage(model);
        setLogInfo(model, order);

        //log.warn("4 " + Long.valueOf(System.currentTimeMillis() - starttime));

        setBranchesForDelegate(model, order);
        setDelegateMessages(model, order);
        setChildMessages(model, order);

        //log.warn("5 " + Long.valueOf(System.currentTimeMillis() - starttime));

        if (ajax != null && !ajax.isEmpty()) {
            return "Order_get_one";
        } else {
            return "Order_get";
        }
    }

    private void setDelegateMessages(Map<String, Object> model, Order order) {
        model.put("delegateMessage", new DelegateMessage());
        List<DelegateMessage> delegateMessageList = delegateMessageService.getByOrder(order);
        setModelParameter(model, "delegateMessageList", delegateMessageList);
    }

    private void setChildMessages(Map<String, Object> model, Order order) {
        Map<Order, List<DelegateMessage>> childMessageMap = new HashMap();
        List<Order> childOrders = order.getChildOrders();
        for (Order childOrder : childOrders) {
            childMessageMap.put(childOrder, delegateMessageService.getByOrder(childOrder));
        }
        setModelParameter(model, "childMessageMap", childMessageMap);
    }

    private void setModelParameter(Map<String, Object> model, String parameterName, Map parameter) {
        model.put(parameterName, (parameter != null ? parameter : new HashMap()));
    }

    private void setBranchesForDelegate(Map<String, Object> model, Order order) {
        List<Branch> branchList = getAllBranches();
        branchList.remove(order.getBranch());
        List<Order> childOrders = order.getChildOrders();
        List<Long> delegatedBranchList = new ArrayList();
        for (Order childOrd : childOrders) {
            if (childOrd.getBranch() != null) {
                delegatedBranchList.add(childOrd.getBranch().getBranchId());
            }
        }
        setModelParameter(model, "branchList", branchList);
        setModelParameter(model, "delegatedBranchList", delegatedBranchList);
    }

    /*
     private void setBranchesForDelegate(Map<String, Object> model, Long orderId) {
     List<Branch> branchList = getAllBranches();
     Set<Long> delegatedBranchList = getDelegatedBranchList(orderId);
     model.put("branchList", branchList);
     model.put("delegatedBranchList", delegatedBranchList);
     }
     */
    private List<Branch> getAllBranches() {
        return branchService.getAll();
    }

    private Set<Long> getDelegatedBranchList(Long orderId) {
        return orderService.getDelegatedBranchList(orderId);
    }

    private void saveOrderView(Order order) {
        orderViewService.saveOrderView(order);
    }

    /*
     @RequestMapping("getFileForClient")
     public void getFileForClient(@RequestParam("fileId") Long fileId, HttpServletResponse response) throws FileNotFoundException, IOException, NotRightException {
     _getFile(response, fileId);
     }
        
     @RequestMapping("getReadyFileForClient")
     public void getReadyFileForClient(@RequestParam("fileId") Long readyFileId, HttpServletResponse response) throws FileNotFoundException, IOException, NotRightException {
     _getFile(response, readyFileId);
     }
     */
    @RequestMapping("getFile")
    public void getFile(@RequestParam("fileId") Long fileId, HttpServletResponse response)
            throws FileNotFoundException, IOException, NotRightException {
        _getFile(response, fileId);
    }

    @RequestMapping("getReadyFile")
    public void getReadyFile(@RequestParam("fileId") Long readyFileId, HttpServletResponse response)
            throws FileNotFoundException, IOException, NotRightException {
        _getFile(response, readyFileId);
    }

    @RequestMapping("/getZipFile")
    public void getZipFile(@RequestParam(value = "files", required = false) Long[] fileIds,
            @RequestParam("orderId") Long orderId, HttpServletResponse response) throws Exception {
        String fileName = "order" + orderId + ".zip";
        byte[] bytes = fileService.getZipFile(fileIds);
        _getFile(response, fileName, bytes);
    }

    @RequestMapping(value = "/getZipFile", params = { "getAllOrderFiles" })
    public void getOrderFilesToZip(@RequestParam(value = "orderId", required = false) Long orderId,
            HttpServletResponse response) throws Exception {
        List<OrderFile> files = fileService.getFilesByOrder(orderId);
        List<Long> fileIds = new ArrayList();
        for (OrderFile file : files) {
            fileIds.add(file.getFileId());
        }
        Long[] fileIdsArr = fileIds.toArray(new Long[0]);
        byte[] bytes = fileService.getZipFile(fileIdsArr);
        String fileName = "order" + orderId + ".zip";
        _getFile(response, fileName, bytes);
    }

    @RequestMapping("/unloading")
    public String unloadingShow(Map<String, Object> model,
            @RequestParam(value = "dateFrom", required = false) Date dateFrom,
            @RequestParam(value = "dateTo", required = false) Date dateTo, HttpServletResponse response)
            throws Exception {
        setInfoForCommonPage(model);
        return "unloading";
    }

    @RequestMapping(value = "/unloading", params = { "submit" })
    public void unloading(Map<String, Object> model,
            @RequestParam(value = "dateFrom", required = false) Date dateFrom,
            @RequestParam(value = "dateTo", required = false) Date dateTo, HttpServletResponse response)
            throws Exception {
        String fileName = "archive.zip";
        if (dateFrom != null && dateTo != null) {
            byte[] bytes = orderService.getOrderFileArchive(dateFrom, dateTo);
            _getFile(response, fileName, bytes);
        } else {
            byte[] bytes = new byte[0];
            _getFile(response, fileName, bytes);
        }
    }

    @RequestMapping("/rate")
    @ResponseBody
    public AjaxResult rate(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam("rate") Integer rate) throws NotRightException {
        checkBranchRight(orderId, "/Order/rate");
        ServiceResult res = orderService.rate(orderId, rate);
        return getAjaxResult(res);
    }

    /**
     *   - ? 
     *
     * @param model
     * @param orderId
     * @return
     */
    @RequestMapping("/confirm")
    @ResponseBody
    public AjaxResult confirm(Map<String, Object> model, @RequestParam("orderId") Long orderId) {
        try {
            ServiceResult res = orderService.confirm(orderId);
            return getAjaxResult(res);
        } catch (Exception e) {
            return new AjaxResult(e.getMessage());
        }
    }

    @RequestMapping("/reject")
    @ResponseBody
    public AjaxResult reject(Map<String, Object> model, @RequestParam("orderId") Long orderId) {
        try {
            ServiceResult res = orderService.reject(orderId);
            return getAjaxResult(res);
        } catch (Exception e) {
            return new AjaxResult(e.getMessage());
        }
    }

    @RequestMapping("/rejectOrConfirm")
    @ResponseBody
    public AjaxResult rejectOrConfirm(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam(value = "confirm", required = false) String confirm)
            throws NotRightException, IOException {
        checkBranchRight(orderId, "/Order/rejectOrConfirm");
        ServiceResult res;
        if (confirm != null && !confirm.isEmpty()) {
            res = orderService.confirm(orderId);
        } else {
            res = orderService.reject(orderId);
        }
        return getAjaxResult(res);
    }

    @RequestMapping("/report")
    public String getReport(Map<String, Object> model,
            @RequestParam(value = "branchId", required = false) Set<Long> brancheIds,
            @RequestParam(value = "orderTypeId", required = false) Set<Long> orderTypeIds,
            @RequestParam(value = "directionId", required = false) Set<Long> directionIds,
            @RequestParam(value = "from", required = false) String from,
            @RequestParam(value = "to", required = false) String to) {
        setInfoForCommonPage(model);
        setInfoForSearch(model);

        Date dateFrom = Converter.getDate(from);
        Date dateTo = Converter.getDate(to);
        ;
        if (dateFrom == null) {
            dateFrom = getStartMonth();
        }
        if (dateTo == null) {
            dateTo = getEndMonth();
        }
        setModelParameter(model, "from", standartFormatDate(dateFrom));
        setModelParameter(model, "to", standartFormatDate(dateTo));

        Set<Long> branchIds = branchRightsHolder.getBranchIds(BranchRights.SEARCH_ORDER);
        List<Payment> paymentList = orderService.getReportAsPaymentList(orderTypeIds, directionIds, brancheIds,
                dateFrom, dateTo, branchIds);

        setModelParameter(model, "paymentList", paymentList);
        setModelParameter(model, "paymentTypeList", paymentTypeService.getActive());

        return "Order_report_asPaymentList";
    }

    @RequestMapping("/readyOrRework")
    @ResponseBody
    public AjaxResult readyOrRework(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam(value = "ready", required = false) String ready) throws NotRightException, IOException {
        checkBranchRight(orderId, "/Order/readyOrRework");
        ServiceResult res;
        if (ready != null && !ready.isEmpty()) {
            res = orderService.ready(orderId);
        } else {
            res = orderService.rework(orderId);
        }
        return getAjaxResult(res);
    }

    /**
     *    ? ? 
     *
     * @param model
     * @param orderId
     * @return
     */
    @RequestMapping("/selectChildToPerform")
    @ResponseBody
    public Map<String, Object> selectChildOrderToPerform(Map<String, Object> model,
            @RequestParam(value = "orderId", required = false) Long orderId) {
        Map<String, Object> resultMap = new HashMap();
        try {
            orderService.selectChildOrderToPerform(orderId);
        } catch (Throwable e) {
            resultMap.put("error", StringAdapter.getStackExeption(e));
        }
        return resultMap;
    }

    /**
     *      
     *
     * @param model
     * @param orderId
     * @return
     */
    @RequestMapping("/unloadInShop")
    @ResponseBody
    public AjaxResult unloadInShop(Map<String, Object> model, @RequestParam("orderId") Long orderId) {
        try {
            ServiceResult result = new ServiceResult();
            orderService.unloadInShop(orderId, result);
            return getAjaxResult(result);
        } catch (Exception e) {
            return new AjaxResult(e.getMessage());
        }
    }

    @RequestMapping("/testsearch")
    public String showAll(Map<String, Object> model,
            @RequestParam(value = "branchId", required = false) Long searchBranchId,
            @RequestParam(value = "orderTypeId", required = false) Set<Long> orderTypeIds,
            @RequestParam(value = "directionId", required = false) Set<Long> directionIds,
            @RequestParam(value = "status", required = false) String statusStr,
            @RequestParam(value = "onlyTable", required = false) String onlyTableStr,
            @RequestParam(value = "searchString", required = false) String searchString,
            @RequestParam(value = "authorId", required = false) Long authorId,
            @RequestParam(value = "overdue", required = false) String overdue,
            @RequestParam(value = "onlyTableRows", required = false) String onlyTableRowsStr,
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
            @RequestParam(value = "haveCost", required = false) String haveCostString,
            @RequestParam(value = "test", required = false) String testString) {

        boolean onlyTable = (onlyTableStr != null && !onlyTableStr.isEmpty());
        boolean onlyTableRows = (onlyTableRowsStr != null && !onlyTableRowsStr.isEmpty());
        boolean haveCost = false;
        if (haveCostString != null && !haveCostString.isEmpty()) {
            haveCost = true;
        }
        if (!onlyTable) {
            setInfoForCommonPage(model, authorId);
        }
        OrderStatus status = null;
        try {
            status = OrderStatus.valueOf(statusStr);
        } catch (Exception e) {
        }

        //long starttime = System.currentTimeMillis();
        boolean test = (testString != null && !testString.isEmpty());

        setInfoForSearch(model);
        Set<Long> rightBrancheIds = branchRightsHolder.getBranchIds(getUrlForOrderSearch());
        removeNull(directionIds);
        removeNull(orderTypeIds);
        OrderSearchData searchData = new OrderSearchData();
        searchData.authorId = authorId;
        searchData.branchIds = getBranchIds(searchBranchId);
        searchData.directionIds = directionIds;
        searchData.orderTypeIds = orderTypeIds;
        searchData.searchString = searchString;
        List<OrderStatus> rightStatusList = getRightsStatusList();
        int numberOfRecords = 100;
        int start = 0;
        if (onlyTableRows) {
            numberOfRecords = 30;
            start = 70;
        }

        if (pageNumber == null) {
            pageNumber = 1;
        }
        start = start + (pageNumber - 1) * numberOfRecords;
        //log.warn("1 " + Long.valueOf(System.currentTimeMillis() - starttime));
        List<OrderListData> list;
        if (!test) {
            if (overdue == null || overdue.isEmpty()) {
                list = orderService.getOrdersAsDataList(rightBrancheIds, status, searchData, start, numberOfRecords,
                        haveCost, rightStatusList);
            } else {
                list = orderService.getOrdersAsOverdueDataList(rightBrancheIds, status, searchData, start,
                        numberOfRecords, haveCost, rightStatusList);
            }
            setPossibleStatuses(list, getRightOrderStatus());

            model.put("orderList", (list != null ? list : new ArrayList()));
        }
        //log.warn("2 " + Long.valueOf(System.currentTimeMillis() - starttime));

        // ?   ?  ?,  ?   
        setModelParameter(model, "overdue", overdue);
        model.put("authorId", authorId);
        model.put("status", status);
        model.put("branchId", searchBranchId);
        List<String> directionNames = getDirectionNames(directionIds);
        setModelParameter(model, "directionNames", (directionNames != null ? directionNames : new ArrayList()));
        List<String> orderTypeNames = getOrderTypesNames(orderTypeIds);
        setModelParameter(model, "orderTypeNames", (orderTypeNames != null ? orderTypeNames : new ArrayList()));
        setModelParameter(model, "haveCost", (haveCostString != null ? haveCostString : ""));
        model.put("orderColorManager", new OrderCssManager(authManager.getCurrentUser()));
        ViewResolver viewResolver = new ViewResolver(authManager.getCurrentUser(), branchRightsHolder);
        model.put("viewResolver", viewResolver);
        model.put("branchRightsHolder", branchRightsHolder);
        setPaymentInfoForSearch(model);

        String userToString = getUserToString();
        setModelParameter(model, "currentUserToString", (userToString != null ? userToString : ""));
        String currentDateToString = getCurrentDateToString();
        setModelParameter(model, "currentDateToString", (currentDateToString != null ? currentDateToString : ""));

        //log.warn("3 " + Long.valueOf(System.currentTimeMillis() - starttime));
        HashMap<String, Boolean> commonRights = new HashMap();
        for (Rights r : Rights.values()) {
            commonRights.put(r.name(), UserRightsUtil.isRight(r));
        }
        model.put("cr", commonRights);
        model.put("br", branchRightsHolder.getBranchRights());

        //log.warn("4 " + Long.valueOf(System.currentTimeMillis() - starttime));
        if (onlyTable) {
            return "Order_table";
        } else if (onlyTableRows) {
            return "Order_table_rows";
        } else {
            return "Order_search";
        }
    }

    @RequestMapping("/getTableData")
    @ResponseBody
    public Map<String, Object> getTableData(Map<String, Object> model,
            @RequestParam(value = "branchId", required = false) Long searchBranchId,
            @RequestParam(value = "orderTypeId", required = false) Set<Long> orderTypeIds,
            @RequestParam(value = "directionId", required = false) Set<Long> directionIds,
            @RequestParam(value = "status", required = false) String statusStr,
            @RequestParam(value = "searchString", required = false) String searchString,
            @RequestParam(value = "authorId", required = false) Long authorId,
            @RequestParam(value = "overdue", required = false) String overdue,
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
            @RequestParam(value = "haveCost", required = false) String haveCostString,
            @RequestParam(value = "onlyTableRows", required = false) String onlyTableRowsStr) {

        Long startTime = System.currentTimeMillis();
        ;

        User currentUser = authManager.getCurrentUser();

        Set<Long> rightBrancheIds = branchRightsHolder.getBranchIds(getUrlForOrderSearch());
        OrderStatus status = null;
        boolean haveCost = (haveCostString != null && !haveCostString.isEmpty());
        boolean overdued = (overdue != null && !overdue.isEmpty());
        boolean onlyTableRows = (onlyTableRowsStr != null && !onlyTableRowsStr.isEmpty());
        try {
            status = OrderStatus.valueOf(statusStr);
        } catch (Exception e) {
        }
        removeNull(directionIds);
        List<String> directionNames = getDirectionNames(directionIds);
        removeNull(orderTypeIds);
        List<String> orderTypeNames = getOrderTypesNames(orderTypeIds);
        OrderSearchData searchData = new OrderSearchData();
        searchData.authorId = authorId;
        searchData.branchIds = getBranchIds(searchBranchId);
        searchData.directionIds = directionIds;
        searchData.orderTypeIds = orderTypeIds;
        searchData.searchString = searchString;

        HashMap<String, Object> params = new HashMap();
        params.put("branchId", searchBranchId);
        params.put("authorId", authorId);
        params.put("status", statusStr);
        params.put("overdue", overdue);
        params.put("haveCost", haveCostString);

        List<OrderStatus> rightStatusList = getRightsStatusList();

        int numberOfRecords = 40;
        int start = 0;
        if (onlyTableRows) {
            numberOfRecords = 40;
            //start = 40;
        }
        if (pageNumber == null) {
            pageNumber = 1;
        }
        start = start + (pageNumber - 1) * numberOfRecords;

        ViewResolver vr = new ViewResolver(currentUser, branchRightsHolder);
        HashMap<String, Object> res = new HashMap();

        res.put("params", params);
        if (!onlyTableRows) {
            res.put("headers", orderService.getOrderListHeaders(directionNames, directionService.getAll(),
                    orderTypeNames, orderTypeService.getAll()));
        }
        res.put("orders", orderService.getOrdersAsTestDataList(rightBrancheIds, status, getRightOrderStatus(),
                searchData, start, numberOfRecords, haveCost, rightStatusList, overdued));

        //log.warn("logicTime: " + Long.valueOf(System.currentTimeMillis() - startTime));
        return res;
    }

    /*@RequestMapping("/getTestTableData")
    @ResponseBody
    public Map<String, Object> getTestTableData(Map<String, Object> model,
        @RequestParam(value = "branchId", required = false) Long searchBranchId,
        @RequestParam(value = "orderTypeId", required = false) Set<Long> orderTypeIds,
        @RequestParam(value = "directionId", required = false) Set<Long> directionIds,
        @RequestParam(value = "status", required = false) String statusStr,
        @RequestParam(value = "searchString", required = false) String searchString,
        @RequestParam(value = "authorId", required = false) Long authorId,
        @RequestParam(value = "overdue", required = false) String overdue,
        @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
        @RequestParam(value = "haveCost", required = false) String haveCostString,
        @RequestParam(value = "onlyTableRows", required = false) String onlyTableRowsStr) {
        
    Long startTime = System.currentTimeMillis();;
        
    User currentUser = authManager.getCurrentUser();
        
    Set<Long> rightBrancheIds = branchRightsHolder.getBranchIds(getUrlForOrderSearch());
    OrderStatus status = null;
    boolean haveCost = (haveCostString != null && !haveCostString.isEmpty());
    boolean overdued = (overdue != null && !overdue.isEmpty());
    boolean onlyTableRows = (onlyTableRowsStr != null && !onlyTableRowsStr.isEmpty());
    try {
        status = OrderStatus.valueOf(statusStr);
    } catch (Exception e) {
    }
    removeNull(directionIds);
    List<String> directionNames = getDirectionNames(directionIds);
    removeNull(orderTypeIds);
    List<String> orderTypeNames = getOrderTypesNames(orderTypeIds);
    OrderSearchData searchData = new OrderSearchData();
    searchData.authorId = authorId;
    searchData.branchIds = getBranchIds(searchBranchId);
    searchData.directionIds = directionIds;
    searchData.orderTypeIds = orderTypeIds;
    searchData.searchString = searchString;
        
    HashMap<String, Object> params = new HashMap();
    params.put("branchId", searchBranchId);
    params.put("authorId", authorId);
    params.put("status", statusStr);
    params.put("overdue", overdue);
    params.put("haveCost", haveCostString);
        
    List<OrderStatus> rightStatusList = getRightsStatusList();
    int numberOfRecords = 100;
    int start = 0;
    if (onlyTableRows) {
        numberOfRecords = 30;
        start = 70;
    }
    if (pageNumber == null) {
        pageNumber = 1;
    }
    start = start + (pageNumber - 1) * numberOfRecords;
    ViewResolver vr = new ViewResolver(currentUser, branchRightsHolder);
    HashMap<String, Object> res = new HashMap();
        
    res.put("params", params);
    if (!onlyTableRows) {
        res.put("headers", orderService.getOrderListHeaders(directionNames, directionService.getAll(), orderTypeNames, orderTypeService.getAll()));
    }
    res.put("orders", orderService.getOrdersAsOrderedDataList(rightBrancheIds, status, getRightOrderStatus(), searchData, start, numberOfRecords, haveCost, rightStatusList, overdued));
        
    //log.warn("logicTime: " + Long.valueOf(System.currentTimeMillis() - startTime));
    return res;
    }*/

    @RequestMapping("/search")
    public String showTestAll(Map<String, Object> model,
            @RequestParam(value = "branchId", required = false) Long searchBranchId,
            @RequestParam(value = "orderTypeId", required = false) Set<Long> orderTypeIds,
            @RequestParam(value = "directionId", required = false) Set<Long> directionIds,
            @RequestParam(value = "status", required = false) String statusStr,
            @RequestParam(value = "onlyTable", required = false) String onlyTableStr,
            @RequestParam(value = "searchString", required = false) String searchString,
            @RequestParam(value = "authorId", required = false) Long authorId,
            @RequestParam(value = "overdue", required = false) String overdue,
            @RequestParam(value = "onlyTableRows", required = false) String onlyTableRowsStr,
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
            @RequestParam(value = "haveCost", required = false) String haveCostString) {

        boolean onlyTable = (onlyTableStr != null && !onlyTableStr.isEmpty());
        boolean onlyTableRows = (onlyTableRowsStr != null && !onlyTableRowsStr.isEmpty());
        boolean haveCost = false;
        if (haveCostString != null && !haveCostString.isEmpty()) {
            haveCost = true;
        }
        if (!onlyTable) {
            setInfoForCommonPage(model, authorId);
        }
        OrderStatus status = null;
        try {
            status = OrderStatus.valueOf(statusStr);
        } catch (Exception e) {
        }

        //long starttime = System.currentTimeMillis();
        setInfoForSearch(model);
        Set<Long> rightBrancheIds = branchRightsHolder.getBranchIds(getUrlForOrderSearch());
        removeNull(directionIds);
        removeNull(orderTypeIds);
        OrderSearchData searchData = new OrderSearchData();
        searchData.authorId = authorId;
        searchData.branchIds = getBranchIds(searchBranchId);
        searchData.directionIds = directionIds;
        searchData.orderTypeIds = orderTypeIds;
        searchData.searchString = searchString;
        List<OrderStatus> rightStatusList = getRightsStatusList();
        int numberOfRecords = 100;
        int start = 0;
        if (onlyTableRows) {
            numberOfRecords = 30;
            start = 70;
        }

        if (pageNumber == null) {
            pageNumber = 1;
        }
        start = start + (pageNumber - 1) * numberOfRecords;
        //log.warn("1 " + Long.valueOf(System.currentTimeMillis() - starttime));
        List<HashMap> list = new ArrayList();
        /*log.warn("2 " + Long.valueOf(System.currentTimeMillis() - starttime));
         log.warn("3 " + Long.valueOf(System.currentTimeMillis() - starttime));*/

        // ?   ?  ?,  ?   
        setModelParameter(model, "overdue", overdue);
        model.put("authorId", authorId);
        model.put("status", status);
        model.put("branchId", searchBranchId);
        model.put("orderList", list);
        List<String> directionNames = getDirectionNames(directionIds);
        setModelParameter(model, "directionNames", (directionNames != null ? directionNames : new ArrayList()));
        List<String> orderTypeNames = getOrderTypesNames(orderTypeIds);
        setModelParameter(model, "orderTypeNames", (orderTypeNames != null ? orderTypeNames : new ArrayList()));
        setModelParameter(model, "haveCost", (haveCostString != null ? haveCostString : ""));
        model.put("orderColorManager", new OrderCssManager(authManager.getCurrentUser()));
        ViewResolver viewResolver = new ViewResolver(authManager.getCurrentUser(), branchRightsHolder);
        model.put("viewResolver", viewResolver);
        model.put("branchRightsHolder", branchRightsHolder);
        setPaymentInfoForSearch(model);

        String userToString = getUserToString();
        setModelParameter(model, "currentUserToString", (userToString != null ? userToString : ""));
        String currentDateToString = getCurrentDateToString();
        setModelParameter(model, "currentDateToString", (currentDateToString != null ? currentDateToString : ""));

        //log.warn("4 " + Long.valueOf(System.currentTimeMillis() - starttime));
        HashMap<String, Boolean> commonRights = new HashMap();
        for (Rights r : Rights.values()) {
            commonRights.put(r.name(), UserRightsUtil.isRight(r));
        }
        model.put("cr", commonRights);
        model.put("br", branchRightsHolder.getBranchRights());

        //log.warn("5 " + Long.valueOf(System.currentTimeMillis() - starttime));
        return "Order_search_test";
    }

    /*@RequestMapping("/searchtest")
    public String showTetestAll(
        Map<String, Object> model,
        @RequestParam(value = "branchId", required = false) Long searchBranchId,
        @RequestParam(value = "orderTypeId", required = false) Set<Long> orderTypeIds,
        @RequestParam(value = "directionId", required = false) Set<Long> directionIds,
        @RequestParam(value = "status", required = false) String statusStr,
        @RequestParam(value = "onlyTable", required = false) String onlyTableStr,
        @RequestParam(value = "searchString", required = false) String searchString,
        @RequestParam(value = "authorId", required = false) Long authorId,
        @RequestParam(value = "overdue", required = false) String overdue,
        @RequestParam(value = "onlyTableRows", required = false) String onlyTableRowsStr,
        @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
        @RequestParam(value = "haveCost", required = false) String haveCostString
    ) {
        
    boolean onlyTable = (onlyTableStr != null && !onlyTableStr.isEmpty());
    boolean onlyTableRows = (onlyTableRowsStr != null && !onlyTableRowsStr.isEmpty());
    boolean haveCost = false;
    if (haveCostString != null && !haveCostString.isEmpty()) {
        haveCost = true;
    }
    if (!onlyTable) {
        setInfoForCommonPage(model, authorId);
    }
    OrderStatus status = null;
    try {
        status = OrderStatus.valueOf(statusStr);
    } catch (Exception e) {
    }
        
    //long starttime = System.currentTimeMillis();
    setInfoForSearch(model);
    Set<Long> rightBrancheIds = branchRightsHolder.getBranchIds(getUrlForOrderSearch());
    removeNull(directionIds);
    removeNull(orderTypeIds);
    OrderSearchData searchData = new OrderSearchData();
    searchData.authorId = authorId;
    searchData.branchIds = getBranchIds(searchBranchId);
    searchData.directionIds = directionIds;
    searchData.orderTypeIds = orderTypeIds;
    searchData.searchString = searchString;
    List<OrderStatus> rightStatusList = getRightsStatusList();
    int numberOfRecords = 100;
    int start = 0;
    if (onlyTableRows) {
        numberOfRecords = 30;
        start = 70;
    }
        
    if (pageNumber == null) {
        pageNumber = 1;
    }
    start = start + (pageNumber - 1) * numberOfRecords;
    List<HashMap> list = new ArrayList();
        
    // ?   ?  ?,  ?   
    setModelParameter(model, "overdue", overdue);
    model.put("authorId", authorId);
    model.put("status", status);
    model.put("branchId", searchBranchId);
    model.put("orderList", list);
    List<String> directionNames = getDirectionNames(directionIds);
    setModelParameter(model, "directionNames", (directionNames != null ? directionNames : new ArrayList()));
    List<String> orderTypeNames = getOrderTypesNames(orderTypeIds);
    setModelParameter(model, "orderTypeNames", (orderTypeNames != null ? orderTypeNames : new ArrayList()));
    setModelParameter(model, "haveCost", (haveCostString != null ? haveCostString : ""));
    model.put("orderColorManager", new OrderCssManager(authManager.getCurrentUser()));
    ViewResolver viewResolver = new ViewResolver(authManager.getCurrentUser(), branchRightsHolder);
    model.put("viewResolver", viewResolver);
    model.put("branchRightsHolder", branchRightsHolder);
    setPaymentInfoForSearch(model);
        
    String userToString = getUserToString();
    setModelParameter(model, "currentUserToString", (userToString != null ? userToString : ""));
    String currentDateToString = getCurrentDateToString();
    setModelParameter(model, "currentDateToString", (currentDateToString != null ? currentDateToString : ""));
        
    //log.warn("4 " + Long.valueOf(System.currentTimeMillis() - starttime));
    HashMap<String, Boolean> commonRights = new HashMap();
    for (Rights r : Rights.values()) {
        commonRights.put(r.name(), UserRightsUtil.isRight(r));
    }
    model.put("cr", commonRights);
    model.put("br", branchRightsHolder.getBranchRights());
        
    //log.warn("5 " + Long.valueOf(System.currentTimeMillis() - starttime));
    return "Order_search_test_1";
    }*/

    private void setModelParameter(Map<String, Object> model, String name, String parameter) {
        model.put(name, (parameter != null ? parameter : ""));
    }

    private void setModelParameter(Map<String, Object> model, String name, List parameter) {
        model.put(name, (parameter != null ? parameter : new ArrayList()));
    }

    private void setModelParameter(Map<String, Object> model, String name, Boolean parameter) {
        model.put(name, (parameter != null ? parameter : false));
    }

    /**
     *    ??,   ? 
     * ?? ?        ??
     * WORKING  REJECTION   ?  
     *
     * @param dataList
     * @param statusList
     */
    private void setPossibleStatuses(List<OrderListData> dataList, List<OrderStatus> statusList) {
        List<Long> toWork = branchRightsHolder.getBranches(BranchRights.ORDER_NEW_TO_WORK);
        List<Long> toReject = branchRightsHolder.getBranches(BranchRights.ORDER_NEW_TO_REJECT);
        for (OrderListData data : dataList) {
            data.possibleStatusList = getPossibleStatuses(data.order, statusList, toWork, toReject);
        }
    }

    private List<OrderStatus> getPossibleStatuses(Order order, List<OrderStatus> statusList, List<Long> toWork,
            List<Long> toReject) {
        Long branchId = (order.getBranch() != null ? order.getBranch().getBranchId() : 0);
        List<OrderStatus> statusListe = new ArrayList();
        statusListe.addAll(statusList);
        if (order.getStatus().equals(OrderStatus.NEW)) {
            if (!toWork.contains(branchId)) {
                statusListe.remove(OrderStatus.WORKING);
            }
            if (!toReject.contains(branchId)) {
                statusListe.remove(OrderStatus.REJECTION);
            }
        }
        return statusListe;
    }

    /**
     *  ? ?? ,   ?   ???
     *
     * @return
     */
    private List<OrderStatus> getRightOrderStatus() {
        List<OrderStatus> statusList = new ArrayList();
        statusList.addAll(Arrays.asList(OrderStatus.values()));
        if (!UserRightsUtil.isRight(Rights.STATUS_NEW)) {
            statusList.remove(OrderStatus.NEW);
        }
        if (!UserRightsUtil.isRight(Rights.STATUS_ARCHIVE)) {
            statusList.remove(OrderStatus.ARCHIVE);
        }
        if (!UserRightsUtil.isRight(Rights.STATUS_CHECK)) {
            statusList.remove(OrderStatus.CHECK);
        }
        if (!UserRightsUtil.isRight(Rights.STATUS_CONFIRMATION)) {
            statusList.remove(OrderStatus.CONFIRMATION);
        }
        if (!UserRightsUtil.isRight(Rights.STATUS_OTHER)) {
            statusList.remove(OrderStatus.OTHER);
        }
        if (!UserRightsUtil.isRight(Rights.STATUS_PRICED)) {
            statusList.remove(OrderStatus.PRICED);
        }
        if (!UserRightsUtil.isRight(Rights.STATUS_READY)) {
            statusList.remove(OrderStatus.READY);
        }
        if (!UserRightsUtil.isRight(Rights.STATUS_REJECTION)) {
            statusList.remove(OrderStatus.REJECTION);
        }
        if (!UserRightsUtil.isRight(Rights.STATUS_REWORK)) {
            statusList.remove(OrderStatus.REWORK);
        }
        if (!UserRightsUtil.isRight(Rights.STATUS_WORKING)) {
            statusList.remove(OrderStatus.WORKING);
        }
        return statusList;
    }

    private void removeNull(Set<Long> set) {
        if (set != null) {
            Iterator iter = set.iterator();
            while (iter.hasNext()) {
                Long l = (Long) iter.next();
                if (l == 0) {
                    iter.remove();
                }
            }
        }
    }

    private String getUserToString() {
        User authUser = authManager.getCurrentUser();
        String userString = "";
        if (authUser != null) {
            userString += authUser.getSurname() + " " + authUser.getName();
        }
        return userString;
    }

    private String getCurrentDateToString() {
        return (new SimpleDateFormat("dd/MM/yy").format(new Date()));
    }

    private void setPaymentInfoForSearch(Map<String, Object> model) {
        model.put("paymentObj", new Payment());
        List<PaymentType> list = paymentTypeService.getActive();
        model.put("paymentTypeList", (list != null ? list : new ArrayList()));
    }

    private Set<Long> getBranchIds(Long branchId) {
        Set<Long> branchIds = new HashSet();
        if (branchId != null) {
            branchIds.add(branchId);
        }
        return branchIds;
    }

    /**
     *      ?? 
     *
     * @param model
     * @return
     */
    @RequestMapping("/deleteRejectionFiles")
    public String deleteRejectionFiles(Map<String, Object> model,
            @RequestParam(value = "submit", required = false) String submit) {
        if (submit != null) {
            orderService.deleteRejectionFiles();
            model.put("message",
                    "   ??   ? ");
        }
        int count = orderService.countRejectionOrdersWithFiles();
        model.put("count", count);
        setInfoForCommonPage(model);
        return "Order_deleteRejectionFiles";
    }

    /**
     * ?  
     *
     * @param model
     * @param date
     * @return
     */
    @RequestMapping(value = "/search", params = { "fromCalendar" })
    public String searchFromCalendar(Map<String, Object> model, @RequestParam("date") Date date) {
        setInfoForCommonPage(model);
        List<OrderStatus> rightStatusList = getRightsStatusList();
        List<OrderListData> orderDataList = orderService.searchFromCalendar(date, rightStatusList);
        model.put("orderDataList", (orderDataList != null ? orderDataList : new ArrayList()));
        model.put("orderCssManager", new OrderCssManager(authManager.getCurrentUser()));
        return "Order_searchFromCalendar";
    }

    @RequestMapping(value = "/getDeadlineDatesForCalendar")
    @ResponseBody
    public Map<String, Object> getDealineDatesForCalendar() {
        List<OrderStatus> rightStatusList = getRightsStatusList();
        List<Date> dateList = orderService.getDeadlineDatesForAuthor(rightStatusList);
        List<String> stringList = new ArrayList();
        SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
        for (Date date : dateList) {
            if (date != null) {
                String str = formatter.format(date);
                stringList.add(str);
            }
        }
        Map<String, Object> resultMap = new HashMap();
        resultMap.put("list", stringList);
        return resultMap;
    }

    /**
     * ?  .
     *
     * @param model
     * @param branchId
     * @return
     */
    /*
     @RequestMapping(value = "/search", params = {"byBranch"})
     public String searchByBranch(
     Map<String, Object> model,
     @RequestParam("branchId") Long branchId
     ) {
     setInfoForCommonPage(model);
     setInfoForSearch(model);
     //List<Order> list = new ArrayList();
     List<OrderListData> list = new ArrayList();
     if (branchRightsHolder.isRight(getUrlForOrderSearch(), branchId)) {
     Set<Long> branchIds = new HashSet();
     branchIds.add(branchId);
     //list = orderService.getOrders(branchIds);
     list = orderService.getOrdersAsDataList(branchIds);
     }
     model.put("orderList", list);
     return "Order_table";
     }
     */
    private List<String> getDirectionNames(Set<Long> directionIds) {
        List<String> list = new ArrayList();
        if (directionIds != null) {
            for (Long directionId : directionIds) {
                if (directionId != null && directionId != 0) {
                    Direction dir = directionService.getOne(directionId.toString());
                    if (dir != null) {
                        list.add(dir.getName());
                    }
                }
            }
        }
        return list;
    }

    private List<String> getOrderTypesNames(Set<Long> orderTypeIds) {
        List<String> list = new ArrayList();
        if (orderTypeIds != null) {
            for (Long orderTypeId : orderTypeIds) {
                if (orderTypeId != null && orderTypeId != 0) {
                    OrderType type = orderTypeService.getOne(orderTypeId.toString());
                    if (type != null) {
                        list.add(type.getName());
                    }
                }
            }
        }
        return list;
    }

    @RequestMapping("/toArchive")
    @ResponseBody
    public AjaxResult toArchive(Map<String, Object> model, @RequestParam("orderId") Long orderId)
            throws NotRightException {
        checkBranchRight(orderId, "/Order/toArchive");
        ServiceResult res = orderService.toArchive(orderId);
        return getAjaxResult(res);
    }

    @RequestMapping("/toCheck")
    @ResponseBody
    public AjaxResult toCheck(Map<String, Object> model, @RequestParam("orderId") Long orderId)
            throws NotRightException {
        checkBranchRight(orderId, "/Order/toCheck");
        ServiceResult res = orderService.toCheck(orderId);
        return getAjaxResult(res);
    }

    @RequestMapping("/changeAuthor")
    @ResponseBody
    public AjaxResult changeAuthor(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam("authorId") Long authorId) {
        try {
            checkBranchRight(orderId, "/Order/changeAuthor");
            orderService.changeAuthor(orderId, authorId);
            return new AjaxResult();
        } catch (Exception e) {
            return new AjaxResult(StringAdapter.getStackExeption(e));
        }
    }

    /**
     *  
     *
     * @param model
     * @param orderId
     * @return
     * @throws IOException
     */
    @RequestMapping("/sendToClient")
    @ResponseBody
    public AjaxResult sendToClient(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam("file_id") Long[] readyFilesIds) throws IOException {
        try {
            checkBranchRight(orderId, "/Order/sendToClient");
        } catch (NotRightException exp) {
            return new AjaxResult("?? ");
        }
        Set<Long> set = new HashSet(Arrays.asList(readyFilesIds));
        orderService.sendToClient(orderId, set);
        return new AjaxResult();
    }

    /**
     *  ?      
     */
    @RequestMapping("/reportForUnloadInShop")
    public String reportForUnloadInShop(Map<String, Object> model,
            @RequestParam(value = "dateFrom", required = false) Date dateFrom,
            @RequestParam(value = "dateTo", required = false) Date dateTo) {
        setInfoForCommonPage(model);

        dateFrom = getDateFrom(dateFrom);
        dateTo = getDateTo(dateTo);
        List<Order> orderList = orderService.reportForUnloadInShop(dateFrom, dateTo);
        setModelParameter(model, "orderList", orderList);
        DateFormatter formatter = new DateFormatter();
        setModelParameter(model, "dateFrom", formatter.date(dateFrom));
        setModelParameter(model, "dateTo", formatter.date(dateTo));
        return "Order_reportForUnload";
    }

    private Date getDateFrom(Date dateFrom) {
        if (dateFrom == null) {
            Calendar cl = Calendar.getInstance();
            cl.set(Calendar.DAY_OF_MONTH, 1);
            dateFrom = cl.getTime();
        }
        return FormatDate.getStartOfDate(dateFrom);
    }

    private Date getDateTo(Date dateTo) {
        if (dateTo == null) {
            dateTo = new Date();
        }
        return FormatDate.getEndOfDate(dateTo);
    }

    /**
     *  ?      ? 
     *
     * @param model
     * @param dateFrom
     * @param dateTo
     * @param ra
     * @return
     */
    @RequestMapping("/unloadMultipleInShop")
    public String unloadMultipleInShop(Map<String, Object> model, @RequestParam("dateFrom") Date dateFrom,
            @RequestParam("dateTo") Date dateTo, RedirectAttributes ra) {
        orderService.unloadMultipleInShop(dateFrom, dateTo);
        DateFormatter formatter = new DateFormatter();
        ra.addAttribute("dateFrom", formatter.date(dateFrom));
        ra.addAttribute("dateTo", formatter.date(dateTo));
        return "redirect:/Order/reportForUnloadInShop";
    }

    @RequestMapping("/testUnloadInShop")
    public String testUnloadInShop() {
        orderService.unloadInShopInCron();
        return "redirect:/Order/reportForUnloadInShop";
    }

    @RequestMapping("/toConfirmation")
    @ResponseBody
    public AjaxResult toConfirmation(Map<String, Object> model, @RequestParam("orderId") Long orderId,
            @RequestParam("authorId") Long authorId) throws NotRightException {
        checkBranchRight(orderId, "/Order/toConfirmation");
        ServiceResult res = orderService.toConfirmation(orderId, authorId);
        return getAjaxResult(res);
    }

    @RequestMapping("/recoverFromReject")
    @ResponseBody
    public AjaxResult recoverFromReject(Map<String, Object> model, @RequestParam("orderId") Long orderId) {
        try {
            orderService.recoverFromReject(orderId);
            return new AjaxResult();
        } catch (Exception e) {
            return new AjaxResult(e.getMessage());
        }
    }

    @RequestMapping("/getOrderLog")
    public String getOrderLog(Map<String, Object> model, @RequestParam("orderId") Long orderId) {
        Order order = orderService.find(orderId);
        setLogInfo(model, order);
        model.put("order", order);
        return "OrderLog_search";
    }

    @RequestMapping("/addNoticesOfPrepayment")
    public String addNoticesOfPrepayment() throws IOException {
        orderService.addNoticesOfPrepayment();
        return "info";
    }

    private String _add(Map<String, Object> model, String submit, Order order, BindingResult result,
            MultipartFile[] files, RedirectAttributes ra) throws IOException {
        // ? ?        
        setComboListsForAddForm(model);
        if (submit != null && !submit.isEmpty()) {
            if (!result.hasErrors()) {

                ServiceResult res = new ServiceResult();
                Long orderId = orderService.addOrder(order, files, res);
                addErrorsToModel(model, res);
                if (!res.hasErrors()) {
                    ra.addFlashAttribute("message",
                            "?     " + orderId);
                    return "redirect:/Order/add";
                }
            }
        }
        model.put("order", order);
        return "Order_add";
    }

    /**
     *    ? 
     *
     * @param model
     * @param order
     */
    private void setLogInfo(Map<String, Object> model, Order order) {
        //  ?   
        List<Payment> payments = paymentService.getByOrderId(order.getOrderId());
        // ? ??  
        List<SmsNotice> smsNotices = noticeService.getNotSystemSmsByOrder(order);
        List<EmailNotice> emailNotices = noticeService.getNotSystemEmailByOrder(order);
        List<OrderLog> logs = orderLogService.getLogsByOrder(order);

        List<LogObject> list = getLogObjetcList(payments, smsNotices, emailNotices, logs);
        setModelParameter(model, "logList", list);
    }

    private List<LogObject> getLogObjetcList(List<Payment> payments, List<SmsNotice> smsNotices,
            List<EmailNotice> emailNotices, List<OrderLog> logs) {
        List<LogObject> list = new ArrayList();
        for (Payment p : payments) {
            LogObject obj = new LogObject(LogObject.Type.PAYMENT, p.getUser(), p.getAmount(), p.getPaymentDate());
            list.add(obj);
        }
        for (SmsNotice not : smsNotices) {
            LogObject obj = new LogObject(LogObject.Type.SMS, not.getUser(), null, not.getNoticeDate());
            list.add(obj);
        }
        for (EmailNotice not : emailNotices) {
            LogObject obj = new LogObject(LogObject.Type.EMAIL, not.getUser(), null, not.getNoticeDate());
            list.add(obj);
        }
        for (OrderLog log : logs) {
            LogObject obj = new LogObject(LogObject.Type.CHANGE_STATUS, null, null, log.getCreateDate());
            obj.firstStatus = log.getFirstStatus();
            obj.secondStatus = log.getSecondStatus();
            obj.insertUser = log.getInsertUser();
            obj.createDate = log.getCreateDate();
            list.add(obj);
        }
        Collections.sort(list);
        return list;
    }

    /**
     *    ?? , ?   
     *
     * @param order
     * @param request
     */
    private void readyMessages(Order order, HttpServletRequest request) {
        User authUser = authManager.getCurrentUser();
        if (authUser instanceof Author) {
            messageService.readyAuthorMessages(order.getOrderId());
        } else if (hasBranchRight(order.getId(), MessageController.SEARCH_AUTHOR_MESSAGE_URL)) {
            messageService.readyAuthorMessages(order.getOrderId());
            messageService.readyAdminMessages(order.getOrderId());
        }
        delegateMessageService.readyMessages(order.getOrderId());
    }

    private void setInfoForSearch(Map<String, Object> model) {
        setModelParameter(model, "branchList", branchService.getAll());
        setModelParameter(model, "typeList", orderTypeService.getAll());
        setModelParameter(model, "directionList", directionService.getAll());
        model.put("statusArray", OrderStatus.values());
    }

    /**
     * ?   , ? ?? ? ? 
     *
     * @param model
     * @param orderId
     * @param order
     */
    private void setInfoForOrder(Map<String, Object> model, Long orderId, Order order) {

        setModelParameter(model, "authors", authorService.getAll());
        setModelParameter(model, "allowToConfirmation", orderService.allowToConfirmation(order));
        setModelParameter(model, "allowConfirm", orderService.allowConfirm(order));
        setModelParameter(model, "allowReject", orderService.allowReject(order));
        setModelParameter(model, "allowRecoverFromReject", orderService.allowRecoverFromReject(order));
        setModelParameter(model, "allowReadyOrRework", orderService.allowReadyOrRework(order));
        setModelParameter(model, "allowToArchive", orderService.allowToArchive(order));
        boolean allowToCheck = orderService.allowToCheck(order);
        setModelParameter(model, "allowToCheck", allowToCheck);
        setModelParameter(model, "allowRate", orderService.allowRate(order));
        setModelParameter(model, "directionList", directionService.getAll());
        setModelParameter(model, "allowAuthorComment", allowAuthorComment(order));
        setModelParameter(model, "existReject", orderService.existRejectForAuthUser(order));
        setModelParameter(model, "allowUnloadedInShop", orderService.allowUnloadedInShop(order));

        setReadyFiles(order, model);
        model.put("statusArray", OrderStatus.values());
        setModelParameter(model, "allowAuthorBlock", allowAuthorBlock(order));
        setModelParameter(model, "adminMessages", messageService.getAdminsByOrder(order));
        setModelParameter(model, "branchList", branchService.getAll());
        setModelParameter(model, "typeList", orderTypeService.getAll());
        setModelParameter(model, "otherOrders", orderService.otherOrdersByClient(order));
        if (order.getStatus().equals(OrderStatus.READY)) {
            setModelParameter(model, "showComment", true);
        }
        if (order.getStatus().equals(OrderStatus.READY) && !order.getReadyFiles().isEmpty()) {
            setModelParameter(model, "showSendClient", true);
        }
        setModelParameter(model, "allowReadyFiles", orderService.allowsReadyFiles(order));

        ViewResolver viewResolver = new ViewResolver(authManager.getCurrentUser(), branchRightsHolder);
        model.put("viewResolver", viewResolver);
        model.put("branchRightsHolder", branchRightsHolder);
    }

    private boolean allowAuthorBlock(Order order) {
        OrderStatus[] statusArray = { OrderStatus.REWORK, OrderStatus.CHECK, OrderStatus.READY, OrderStatus.ARCHIVE,
                OrderStatus.OTHER, OrderStatus.REJECTION };
        List<OrderStatus> statusList = Arrays.asList(statusArray);
        OrderStatus status = order.getStatus();
        if (status != null) {
            if (statusList.contains(status)) {
                return true;
            }
        }
        return false;
    }

    private boolean allowAuthorComment(Order order) {
        OrderStatus[] arr = { OrderStatus.WORKING, OrderStatus.CHECK, OrderStatus.READY, OrderStatus.ARCHIVE,
                OrderStatus.OTHER, OrderStatus.REWORK };
        List<OrderStatus> list = Arrays.asList(arr);
        return list.contains(order.getStatus());
    }

    private void setReadyFiles(Order order, Map<String, Object> model) {
        List<ReadyOrderFile> readyFiles = order.getReadyFiles();
        ReadyOrderFile allotedFile = null;
        if (readyFiles.size() > 1) {
            ReadyOrderFile last = readyFiles.get(readyFiles.size() - 1);
            ReadyOrderFile lastButOne = readyFiles.get(readyFiles.size() - 2);
            if (differentDates(last, lastButOne)) {
                readyFiles.remove(last);
                allotedFile = last;
            }
        }
        setModelParameter(model, "readyFiles", readyFiles);
        if (allotedFile != null) {
            model.put("lastReadyFile", allotedFile);
        }
    }

    private boolean differentDates(ReadyOrderFile last, ReadyOrderFile lastByOne) {
        Date lastDate = last.getUploadDate();
        Date lastByOneDate = lastByOne.getUploadDate();
        Calendar clLast = Calendar.getInstance();
        clLast.setTime(lastDate);
        Calendar clLastByOne = Calendar.getInstance();
        clLastByOne.setTime(lastByOneDate);
        return (clLast.get(Calendar.DAY_OF_MONTH) != clLastByOne.get(Calendar.DAY_OF_MONTH)
                || clLast.get(Calendar.MONTH) != clLastByOne.get(Calendar.MONTH)
                || clLast.get(Calendar.YEAR) != clLastByOne.get(Calendar.YEAR));
    }

    /*
     private void setReadyFiles(Order order, Map<String, Object> model) {
     List<ReadyOrderFile> readyFiles = order.getReadyFiles();
     if (readyFiles.size() > 0) {
     int lastIdx = readyFiles.size() - 1;
     List<ReadyOrderFile> resultReadyFiles = readyFiles.subList(0, lastIdx);
     ReadyOrderFile lastFile = readyFiles.get(lastIdx);
     model.put("readyFiles", resultReadyFiles);
     model.put("lastReadyFile", lastFile);
     }
     }
     */
    private void setAuthorMessages(Map<String, Object> model, Order order) {
        User authUser = authManager.getCurrentUser();
        setModelParameter(model, "allowSendToAll", alllowSendAuthorMessagesToAll(order, authUser));
        if (authUser instanceof Admin) {
            AuthorMessageData data = messageService.getAuthorMessagesForAdmin(order);
            setModelParameter(model, "hasAuthorMessages", (data.authorMessages != null));
            setModelParameter(model, "authorMessages", data.authorMessages);
            model.put("otherMessageMap", data.otherMessages);
            model.put("orderAuthor", order.getAuthor());
        } else {
            Author author = (Author) authUser;
            List<AuthorMessage> messages = messageService.getAuthorMessagesForAuthor(order, author);
            setModelParameter(model, "messageList", messages);
            model.put("author", author);
            model.put("orderAuthor", order.getAuthor());
            model.put("salary", authorSalaryService.getSalary(author.getUserId(), order.getOrderId()));
            //model.put("author", author);
            //model.put("orderAuthor", order.getAuthor());
        }
    }

    private boolean alllowSendAuthorMessagesToAll(Order order, User authUser) {
        return (authUser instanceof Admin && order.getAuthor() == null);
    }

    /**
     * ?   ?? 
     *
     * @param model
     * @param order
     */
    /*
     private void setAuthorMessages(Map<String, Object> model, Order order) {
     Map<Author, List<AuthorMessage>> otherMap = new LinkedHashMap();
     User authUser = authManager.getCurrentUser();
     Map<Author, List<AuthorMessage>> allMessages = messageService.getAllAuthorMessagesByOrder(order);
     // ?   - 
     if (authUser instanceof Admin) {
     // ? ?? ? ?  
     Author orderAuthor = order.getAuthor();
     if (orderAuthor != null) {
     model.put("orderAuthor", orderAuthor);
     model.put("authorMessages", allMessages.get(orderAuthor));
        
     allMessages.remove(orderAuthor);
     }
     // ? ?? ? ?  
     otherMap.putAll(allMessages);
     } else {
     // ?   - 
     Author author = (Author) authUser;
     // ? ?? ?  ? 
     model.put("orderAuthor", author);
     model.put("authorMessages", allMessages.get(author));
     }
     model.put("otherMessageMap", otherMap);
     }
     */
    private void setInfoForPayment(Map<String, Object> model, Long orderId) {
        Payment payment = new Payment();
        model.put("obj", payment);
        model.put("paymentTypeList", paymentTypeService.getActive());
    }

    /**
     * ?      ??, ?  
     * 
     *
     * @param model
     */
    private void setInfoForMessage(Map<String, Object> model) {
        AdminMessage adminMessage = new AdminMessage();
        model.put("adminMessage", adminMessage);
        AuthorMessage authorMessage = new AuthorMessage();
        model.put("authorMessage", authorMessage);
    }

    private void _addFiles(Map<String, Object> model, Long orderId, MultipartFile[] files)
            throws IOException, NotRightException {
        Order obj = orderService.find(orderId);
        checkBranchRight(obj, "/Order/addFile");
        for (MultipartFile file : files) {
            orderService.addFile(obj, file);
        }
    }

    private void _addFile(Map<String, Object> model, Long orderId, MultipartFile file)
            throws IOException, NotRightException {
        Order obj = orderService.find(orderId);
        checkBranchRight(obj, "/Order/addFile");
        orderService.addFile(obj, file);
    }

    private Set<Long> getBranchIdsForContacts() {
        return branchRightsHolder.getBranchIds("/Order/contacts");
    }

    private void getXls(HttpServletResponse response, Set<Long> rightBranchIds, ReportFormData data, String type)
            throws IOException {
        Set<String> set = getPhonesOrEmails(rightBranchIds, data, type);
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet("FirstSheet");
        int n = 0;
        for (String str : set) {
            HSSFRow rowhead = sheet.createRow((short) n);
            rowhead.createCell(0).setCellValue(str);
            n++;
        }
        String fileName = "contacts.xls";
        if (type.equals(TYPE_PHONE)) {
            fileName = "phones.xls";
        } else if (type.equals(TYPE_EMAIL)) {
            fileName = "emails.xls";
        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        workbook.write(response.getOutputStream());
    }

    private Set<String> getPhonesOrEmails(Set<Long> rightBrancheIds, ReportFormData data, String type) {
        Set<String> set = new HashSet();
        if (type.equals(TYPE_EMAIL)) {
            set = orderService.getEmails(rightBrancheIds, data);
        } else if (type.equals(TYPE_PHONE)) {
            set = orderService.getPhones(rightBrancheIds, data);
        }
        return set;
    }

    private String standartFormatDate(Date date) {
        String str = "";
        if (date != null) {
            SimpleDateFormat dt = new SimpleDateFormat("dd.MM.YYYY");
            str = dt.format(date);
        }
        return str;
    }

    private Date getStartMonth() {
        Calendar cl = Calendar.getInstance();
        cl.set(Calendar.DAY_OF_MONTH, 1);
        cl.set(Calendar.HOUR_OF_DAY, 0);
        cl.set(Calendar.MINUTE, 0);
        cl.set(Calendar.SECOND, 0);
        return cl.getTime();
    }

    private Date getEndMonth() {
        Calendar cl = Calendar.getInstance();
        cl.set(Calendar.DAY_OF_MONTH, cl.getActualMaximum(Calendar.DAY_OF_MONTH));
        cl.set(Calendar.HOUR_OF_DAY, 23);
        cl.set(Calendar.MINUTE, 59);
        cl.set(Calendar.SECOND, 59);
        return cl.getTime();
    }

    private void setComboListsForAddForm(Map<String, Object> model) {
        setModelParameter(model, "orderTypeList", orderTypeService.getAll());
        setModelParameter(model, "directionList", directionService.getAll());
        setModelParameter(model, "branchList",
                branchService.getList(branchRightsHolder.getBranchIds("/Order/add")));
    }

    private void setComboLists(Map<String, Object> model) {
        setModelParameter(model, "orderTypeList", orderTypeService.getAll());
        setModelParameter(model, "directionList", directionService.getAll());
        setModelParameter(model, "branchList", branchService.getAll());
    }

    /**
     *    fileId
     *
     * @param fileId
     * @param url
     * @throws NotRightException
     */
    protected void checkRightsByOrderFileId(Long fileId, String url) throws NotRightException {
        OrderFile of = fileService.findOrderFile(fileId);
        branchRightsHolder.checkRight(url, of.getOrder().getBranch().getBranchId());
    }

    /**
     *    readyFileId
     *
     * @param fileId
     * @param url
     * @throws NotRightException
     */
    protected void checkRightsByReadyFileId(Long readyFileId, String url) throws NotRightException {
        ReadyOrderFile of = fileService.findReadyOrderFile(readyFileId);
        branchRightsHolder.checkRight(url, of.getOrder().getBranch().getBranchId());
    }

}