/*******************************************************************************
 * Copyright 2014 2Fi Business Solutions Ltd.
 *
 * This code is part of the PCS project.
 *
 * This code is copyrighted. Under no circumstances should any party, people,
 * or organization should redistribute any portions of this code in any form,
 * either verbatim or through electronic media, to any third parties, unless
 * under explicit written permission by 2Fi Business Solutions Ltd.
 ******************************************************************************/
package com.ffii.tbms.order.web;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.SerializationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.ffii.core.utils.CriteriaUtils;
import com.ffii.core.utils.MapUtils;
import com.ffii.core.utils.NumberUtils;
import com.ffii.core.utils.Params;
import com.ffii.core.utils.SecurityUtils;
import com.ffii.core.utils.web.ServletRequestUtils;
import com.ffii.core.web.AbstractController;
import com.ffii.core.web.view.json.JsonView;
import com.ffii.tbms.customer.Customer;
import com.ffii.tbms.customer.service.CustomerService;
import com.ffii.tbms.file.FileRefType;
import com.ffii.tbms.file.service.FileService;
import com.ffii.tbms.log.LogUtils;
import com.ffii.tbms.log.service.AuditLogService;
import com.ffii.tbms.order.Order;
import com.ffii.tbms.order.service.OrderService;

@Controller
@RequestMapping(value = "/order")
public class OrderController extends AbstractController {

	@Autowired
	private OrderService orderService;

	@Autowired
	private FileService fileService;

	@Autowired
	private CustomerService customerService;

	@Autowired
	private StandardPasswordEncoder passwordEncoder;

	@RequestMapping(value = "/save", method = RequestMethod.POST)
	public String save(final Model model, final HttpServletRequest request,
			@RequestParam(defaultValue = "-1") Integer id) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN") || SecurityUtils.isGranted("WORKSHOP_MAINTAIN")) {
			Order instance;
			Order oldRecord = new Order();
			if (id > 0) {
				instance = orderService.find(id);
				oldRecord = SerializationUtils.clone(instance);
			} else {
				instance = new Order();
			}

			ServletRequestUtils.doBind(request, instance, null);
			if(instance.getStatus() != Order.STATUS_ON_HAND){
				instance.setTargetCompleteDate(null);
			}

			id = orderService.saveOrUpdate(instance);

			if(oldRecord.getId() != null){
				orderService.log(LogUtils.ACTION_UPDATE, id, instance, oldRecord);
			}else{
				orderService.log(LogUtils.ACTION_CREATE, id, instance);
			}

			orderService.updateChildOrder(instance);
			model.addAttribute(Params.ID, id);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/delete", method = RequestMethod.POST)
	public String delete(final Model model, final HttpServletRequest request, @RequestParam final Integer id)
			throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN")) {

			// find, mark delete, and save
			orderService.deletedOrder(id);

			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/load", method = { RequestMethod.GET, RequestMethod.POST })
	public String load(final Model model, final HttpServletRequest request, @RequestParam final Integer id)
			throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN") || SecurityUtils.isGranted("WORKSHOP_MAINTAIN")) {
			final Map<String, Object> data = orderService.queryForMap(id);

			model.addAttribute(Params.DATA, data);
			model.addAttribute(Params.SUCCESS, data != null);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/combo.json", method = { RequestMethod.GET, RequestMethod.POST })
	public String comboJson(final Model model, final HttpServletRequest request) throws Exception {

		final Map<String, Object> args = new HashMap<String, Object>();

		CriteriaUtils.addInteger(request, args, Params.ID);
		CriteriaUtils.addInteger(request, args, "custId");
		CriteriaUtils.addStringLike(request, args, Params.QUERY);

		final List<Map<String, Object>> records = orderService.searchForCombo(args);

		model.addAttribute(Params.RECORDS, records);

		return JsonView.NAME;
	}

	@RequestMapping(value = "/list.json", method = { RequestMethod.GET, RequestMethod.POST })
	public String listJson(final Model model, final HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN") || SecurityUtils.isGranted("CUSTOMER_MAINTAIN")) {
			final Map<String, Object> args = new HashMap<String, Object>();

			CriteriaUtils.addStringLike(request, args, Params.QUERY);

			CriteriaUtils.addInteger(request, args, Params.ID);
			CriteriaUtils.addString(request, args, "orderType");
			CriteriaUtils.addStringLike(request, args, "orderCode");
			CriteriaUtils.addStringLike(request, args, "firstName");
			CriteriaUtils.addStringLike(request, args, "surname");
			CriteriaUtils.addStringLike(request, args, "nameCh");
			CriteriaUtils.addStringLike(request, args, "emailPhone");
			CriteriaUtils.addDate(request, args, "fromDate");
			CriteriaUtils.addDateTo(request, args, "toDate");
			CriteriaUtils.addStringLike(request, args, "itemName");
			CriteriaUtils.addInteger(request, args, "custId");
			CriteriaUtils.addInteger(request, args, "status");
			CriteriaUtils.addBoolean(request, args, "balance");
			//CriteriaUtils.addBoolean(request, args, "showIgnored");
			CriteriaUtils.addDate(request, args, "targetCompleteDateFrom");
			CriteriaUtils.addDateTo(request, args, "targetCompleteDateTo");
			CriteriaUtils.addInteger(request, args, "start");
			CriteriaUtils.addInteger(request, args, "limit");
			

			String orderNos = ServletRequestUtils.getStringParameter(request, "orderNo");
			String orderNoStr = getSearchOrderString(orderNos);
			if((orderNos!=null && !orderNos.equals("")) 
				&& (orderNoStr==null || orderNoStr.equals(""))){
				model.addAttribute(Params.RECORDS, new ArrayList<>());
				model.addAttribute("total", 0);
				model.addAttribute("totalAmount",0);
				model.addAttribute(Params.SUCCESS, Boolean.TRUE);
				return JsonView.NAME;
			}else if(orderNos!=null && !orderNos.equals("")){
				args.put("orderNoStr", orderNoStr);
			}
			List<Map<String, Object>> records = orderService.search(args);
			Map<String, Object> count = orderService.countSearch(args);
			Map<String, Object> totalAmount = orderService.sumTotalAmount(args);

			model.addAttribute(Params.RECORDS, records);
			model.addAttribute("total", NumberUtils.intValue(count.get("count")));
			model.addAttribute("totalAmount",  NumberUtils.toDecimal(totalAmount.get("totalAmount"),BigDecimal.ZERO));
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	private String getSearchOrderString(String orderNoStr){
		if(orderNoStr==null) return "";
		String str = "";
		String[] orderArray = orderNoStr.trim().split(",");
		for(String orderNo: orderArray){
			if(!str.equals("")){
				str = str + " OR ";
			}
			String[] orderRange = orderNo.trim().split("to");
			if(orderRange.length>1){
				String[] from = orderRange[0].trim().split("[^A-Za-z0-9]+|(?<=[A-Za-z])(?=[0-9])|(?<=[0-9])(?=[A-Za-z])");
				String[] to = orderRange[1].trim().split("[^A-Za-z0-9]+|(?<=[A-Za-z])(?=[0-9])|(?<=[0-9])(?=[A-Za-z])");
				Integer fromCode, toCode;
				String type;
				if(from.length<2) return "";

				type = from[0]+"-";
				fromCode = NumberUtils.toInt(from[1], null);
				if(fromCode == null) return "";

				if(to.length==0)
					return "";
				if(to.length==1)
					toCode = NumberUtils.toInt(to[0], null);
				else
					toCode = NumberUtils.toInt(to[1], null);
				if(toCode == null) return "";

				str = str+" (o.type ='"+type+"' AND o.code >="+fromCode+" AND o.code <= "+toCode+") ";
			}else{
				String[] orderTypeCode = orderNo.trim().split("[^A-Za-z0-9]+|(?<=[A-Za-z])(?=[0-9])|(?<=[0-9])(?=[A-Za-z])");
				if(orderTypeCode.length>1){
					str = str+" (o.type ='"+orderTypeCode[0]+"-' AND o.code = "+orderTypeCode[1]+") ";
				}else if(NumberUtils.toInt(orderTypeCode[0], null)!= null){
					str = str+" o.code = "+orderTypeCode[0]+" ";
				}else{
					str = str+" o.type = '"+orderTypeCode[0]+"-' ";
				}
				
			}
		}

		logger.info("orderNoStr : "+str);
		
		return " AND ( "+str+" ) ";
	}

	@RequestMapping(value = "/list-for-workshop.json", method = { RequestMethod.GET, RequestMethod.POST })
	public String listForWorkshopJson(final Model model, final HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("WORKSHOP_MAINTAIN")) {
			final Map<String, Object> args = new HashMap<String, Object>();

			CriteriaUtils.addStringLike(request, args, Params.QUERY);

			CriteriaUtils.addInteger(request, args, Params.ID);
		
			CriteriaUtils.addStringLike(request, args, "firstName");
			CriteriaUtils.addStringLike(request, args, "surname");
			CriteriaUtils.addStringLike(request, args, "nameCh");
			CriteriaUtils.addStringLike(request, args, "emailPhone");
			CriteriaUtils.addDate(request, args, "fromOutDate");
			CriteriaUtils.addDateTo(request, args, "toOutDate");
			CriteriaUtils.addInteger(request, args, "workshopStatus");
			CriteriaUtils.addInteger(request, args, "stockInStatus");
			//CriteriaUtils.addBoolean(request, args, "showIgnored");
			CriteriaUtils.addDate(request, args, "workshopTargetDateFrom");
			CriteriaUtils.addDateTo(request, args, "workshopTargetDateTo");

			CriteriaUtils.addInteger(request, args, "start");
			CriteriaUtils.addInteger(request, args, "limit");

			//args.put("showIgnored", true);


			String orderNos = ServletRequestUtils.getStringParameter(request, "orderNo");
			String orderNoStr = getSearchOrderString(orderNos);
			if((orderNos!=null && !orderNos.equals("")) 
				&& (orderNoStr==null || orderNoStr.equals(""))){
				model.addAttribute(Params.RECORDS, new ArrayList<>());
				model.addAttribute("total", 0);
				model.addAttribute("totalAmount",0);
				model.addAttribute(Params.SUCCESS, Boolean.TRUE);
				return JsonView.NAME;
			}else if(orderNos!=null && !orderNos.equals("")){
				args.put("orderNoStr", orderNoStr);
			}
			final List<Map<String, Object>> records = orderService.searchForWorkShop(args);
			final Map<String, Object> count = orderService.countSearchForWorkshop(args);

			model.addAttribute(Params.RECORDS, records);
			model.addAttribute("total", NumberUtils.intValue(count.get("count")));
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}
		return JsonView.NAME;
	}

	@RequestMapping(value = "/list/on-hand", method = RequestMethod.POST)
	public String onHandOrders(final Model model, final HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN")) {
			final int[] ids = ServletRequestUtils.getIntParameters(request, "ids");
			if (ids != null) {
				for (int id : ids) {
					final Order instance = orderService.find(id);
					instance.setStatus(Order.STATUS_ON_HAND);
					id = orderService.saveOrUpdate(instance);
					orderService.log(LogUtils.ACTION_UPDATE,
									id, 
									MapUtils.toHashMap("statue", Order.STATUS_ON_HAND));
					orderService.updateChildOrder(instance);
				}
			}
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}
	
	@RequestMapping(value = "/list/complete", method = RequestMethod.POST)
	public String completeOrders(final Model model, final HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN")) {
			final int[] ids = ServletRequestUtils.getIntParameters(request, "ids");
			if (ids != null) {
				for (int id : ids) {
					final Order instance = orderService.find(id);
					instance.setStatus(Order.STATUS_COMPLETED);
					instance.setTargetCompleteDate(null);
					id = orderService.saveOrUpdate(instance);
					orderService.log(LogUtils.ACTION_UPDATE,
									id, 
									MapUtils.toHashMap("statue", Order.STATUS_COMPLETED));
					orderService.updateChildOrder(instance);
				}
			}
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/list/cancel", method = RequestMethod.POST)
	public String cancelOrders(final Model model, final HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN") && SecurityUtils.isGranted("ORDER_CANCEL")) {
			final int[] ids = ServletRequestUtils.getIntParameters(request, "ids");
			if (ids != null) {
				for (int id : ids) {
					final Order instance = orderService.find(id);
					instance.setStatus(Order.STATUS_CANCELLED);
					instance.setTargetCompleteDate(null);
					id = orderService.saveOrUpdate(instance);
					orderService.log(LogUtils.ACTION_UPDATE,
									id, 
									MapUtils.toHashMap("statue", Order.STATUS_CANCELLED));
					orderService.updateChildOrder(instance);
				}
			}
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
			model.addAttribute(Params.AUTH, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/list/ignore", method = RequestMethod.POST)
	public String ignoreOrders(final Model model, final HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN") && SecurityUtils.isGranted("ORDER_CANCEL")) {
			final int[] ids = ServletRequestUtils.getIntParameters(request, "ids");
			if (ids != null) {
				for (int id : ids) {
					final Order instance = orderService.find(id);
					instance.setStatus(Order.STATUS_IGNORE);
					instance.setTargetCompleteDate(null);
					id = orderService.saveOrUpdate(instance);
					orderService.log(LogUtils.ACTION_UPDATE,
									id, 
									MapUtils.toHashMap("statue", Order.STATUS_IGNORE));
					orderService.updateChildOrder(instance);
				}
			}
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
			model.addAttribute(Params.AUTH, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/complete", method = RequestMethod.POST)
	public String complete(final Model model, final HttpServletRequest request,
			@RequestParam(defaultValue = "-1") Integer id) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN")) {
			Order instance;
			instance = orderService.find(id);
			instance.setStatus(Order.STATUS_COMPLETED);
			id = orderService.saveOrUpdate(instance);
			instance.setTargetCompleteDate(null);
			orderService.updateChildOrder(instance);

			model.addAttribute(Params.ID, id);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/workshop/list/complete", method = RequestMethod.POST)
	public String workshopComplete(final Model model, final HttpServletRequest request) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN") ||  SecurityUtils.isGranted("WORKSHOP_MAINTAIN")) {
			final int[] ids = ServletRequestUtils.getIntParameters(request, "ids");
			if (ids != null) {
				for (int id : ids) {
					final Order instance = orderService.find(id);
					instance.setWorkshopStatus(Order.WS_WORK_STATUS_COMPLETED);
					id = orderService.saveOrUpdate(instance);
					orderService.log(LogUtils.ACTION_UPDATE,
									id, 
									MapUtils.toHashMap("workshopStatus", Order.WS_WORK_STATUS_COMPLETED));
					orderService.updateChildOrder(instance);
				}
			}
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/workshop/change-status", method = RequestMethod.POST)
	public String workshopChangeStatus(final Model model, final HttpServletRequest request,
			@RequestParam(defaultValue = "-1") Integer id, Integer workshopStatus) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN")||  SecurityUtils.isGranted("WORKSHOP_MAINTAIN")) {
			Integer outStatus = NumberUtils.toInt(ServletRequestUtils.getStringParameter(request, "outStatus"), null);

			final Order instance = orderService.find(id);
			instance.setWorkshopStatus(workshopStatus);
			instance.setOutStatus(outStatus);
			
			id = orderService.saveOrUpdate(instance);

			model.addAttribute(Params.ID, id);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/cancel", method = RequestMethod.POST)
	public String cancel(final Model model, final HttpServletRequest request,
			@RequestParam(defaultValue = "-1") Integer id) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN")) {
			final Order instance = orderService.find(id);
			instance.setStatus(Order.STATUS_CANCELLED);
			instance.setTargetCompleteDate(null);
			id = orderService.saveOrUpdate(instance);
			orderService.updateChildOrder(instance);

			model.addAttribute(Params.ID, id);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/image-list.json", method = { RequestMethod.GET, RequestMethod.POST })
	public String imageListJson(final Model model, final HttpServletRequest request, @RequestParam final Integer id)
			throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN") ||  SecurityUtils.isGranted("WORKSHOP_MAINTAIN")) {
			final Map<String, Object> args = new HashMap<String, Object>();
			args.put("refType", FileRefType.ORDER);
			args.put("refId", id);

			final List<Map<String, Object>> records = fileService.searchFiles(args);

			model.addAttribute(Params.RECORDS, records);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}
		return JsonView.NAME;
	}

	@RequestMapping(value = "/get-current-ms.json", method = { RequestMethod.GET, RequestMethod.POST })
	public String getCurrentMS(Model model, HttpServletRequest request,
			@RequestParam(required = false) Integer orderId) {

		Order order = orderService.find(orderId);

		Map<String, Object> args = new HashMap<String, Object>();
		List<Map<String, Object>> records = new ArrayList<>();
		if (order != null && order.getFileId() != null && order.getFileId() > 0) {
			args.put("fileId", order.getFileId());
			args.put("refType", FileRefType.MEASUREMENT_SHEET);
			records = fileService.searchFiles(args);
		}
		model.addAttribute(Params.RECORDS, records);
		model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		return JsonView.NAME;
	}

	@RequestMapping(value = "/updateindate", method = { RequestMethod.GET, RequestMethod.POST })
	public String updateInDate(Model model, HttpServletRequest request  ) throws Exception {

		Integer orderId = ServletRequestUtils.getIntParameter(request, "id");
		Date inDate = ServletRequestUtils.getDateParameter(request, "inDate");
		String inRemark = ServletRequestUtils.getStringParameter(request, "inRemark");
		Integer inStatus = NumberUtils.toInt(ServletRequestUtils.getStringParameter(request, "inStatus"), null);
		
		Order instance = orderService.find(orderId);
		ServletRequestUtils.doBind(request, instance, null);
		if(Order.IN_OUT_STATUS_RECEIVED == inStatus){
			instance.setWorkshopStatus(null);
		}
		orderService.saveOrUpdate(instance);

		orderService.log(LogUtils.ACTION_UPDATE,
									orderId, 
									MapUtils.toHashMap(
										"inDate", instance.getInDate(),
										"inRemark",instance.getInRemark(),
										"workshopStatus", instance.getWorkshopStatus(),
										"inStatus", instance.getInStatus()
									));
		
		model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		return JsonView.NAME;
	}

	@RequestMapping(value = "/updateoutdate", method = { RequestMethod.GET, RequestMethod.POST })
	public String updateOutDate(Model model, HttpServletRequest request) throws Exception {

		Integer orderId = ServletRequestUtils.getIntParameter(request, "id");
		Date outDate = ServletRequestUtils.getDateParameter(request, "outDate");
		String outRemark = ServletRequestUtils.getStringParameter(request, "outRemark");
		Integer outStatus =  NumberUtils.toInt(ServletRequestUtils.getStringParameter(request, "outStatus"), null);

		
		Order instance = orderService.find(orderId);
		ServletRequestUtils.doBind(request, instance, null);
		instance.setInDate(null);
		instance.setInRemark(null);
		instance.setInStatus(null);
		Map<String, Object> diff = MapUtils.toHashMap(
			"outDate", instance.getOutDate(),
			"outRemark", instance.getOutRemark(),
			"outStatus", instance.getOutStatus(),
			"inDate", instance.getInDate(),
			"inRemark",instance.getInRemark(),
			"inStatus",instance.getInStatus()
		);
		if(instance.getWorkshopStatus() == null){
			instance.setWorkshopStatus(Order.WS_WORK_STATUS_PENDING);
			diff.put("workshopStatus",  instance.getWorkshopStatus());
		}
		orderService.saveOrUpdate(instance);

		orderService.log(LogUtils.ACTION_UPDATE, orderId, diff);

		model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		return JsonView.NAME;
	}

	@RequestMapping(value = "/workshop/updateindate", method = { RequestMethod.GET, RequestMethod.POST })
	public String updateWorkshopInDate(Model model, HttpServletRequest request ) throws Exception {

		Integer orderId = ServletRequestUtils.getIntParameter(request, "id");
		//order out = workshop in
		Integer outStatus = NumberUtils.toInt(ServletRequestUtils.getStringParameter(request, "outStatus"), null);
		
		Order instance = orderService.find(orderId);
		instance.setOutStatus(outStatus);
		orderService.saveOrUpdate(instance);

		orderService.log(LogUtils.ACTION_UPDATE,
									orderId, 
									MapUtils.toHashMap(
										"outStatus", instance.getOutStatus()
									));
		
		model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		return JsonView.NAME;
	}

	@RequestMapping(value = "/workshop/updateoutdate", method = { RequestMethod.GET, RequestMethod.POST })
	public String updateWorkshopOutDate(Model model, HttpServletRequest request) throws Exception {

		Integer orderId = ServletRequestUtils.getIntParameter(request, "id");

		//order in = workshop out
		Date inDate = ServletRequestUtils.getDateParameter(request, "inDate");
		String inRemark = ServletRequestUtils.getStringParameter(request, "inRemark");
		Integer inStatus =  NumberUtils.toInt(ServletRequestUtils.getStringParameter(request, "inStatus"), null);

		
		Order instance = orderService.find(orderId);
		instance.setInDate(inDate);
		instance.setInRemark(inRemark);
		instance.setInStatus(inStatus);

		Map<String, Object> diff = MapUtils.toHashMap(
			"inDate", instance.getInDate(),
			"inRemark",instance.getInRemark(),
			"inStatus",instance.getInStatus()
		);
		orderService.saveOrUpdate(instance);

		orderService.log(LogUtils.ACTION_UPDATE, orderId, diff);

		model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		return JsonView.NAME;
	}

	@RequestMapping(value = "/create-cust", method = { RequestMethod.GET, RequestMethod.POST })
	public String quickCreateCust(Model model, HttpServletRequest request) throws Exception {
		if (SecurityUtils.isGranted("ORDER_MAINTAIN") || SecurityUtils.isGranted("WORKSHOP_MAINTAIN")) {
			Customer instance = new Customer();

			ServletRequestUtils.doBind(request, instance, null);

			int id = customerService.saveOrUpdate(instance);

			model.addAttribute(Params.ID, id);
			model.addAttribute(Params.SUCCESS, Boolean.TRUE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	
	@RequestMapping(value = "/check-order-no", method = { RequestMethod.GET, RequestMethod.POST })
	public String checkValidOrderNo(Model model, HttpServletRequest request) throws Exception {
		if (SecurityUtils.isGranted("ORDER_MAINTAIN") || SecurityUtils.isGranted("WORKSHOP_MAINTAIN")) {

			Map<String, Object> args = new HashMap<String, Object>();

			CriteriaUtils.addString(request, args, "type");
			CriteriaUtils.addString(request, args, "code");
			CriteriaUtils.addInteger(request, args, "id");

			if(!args.containsKey("id")){
				args.put("id", 0);
			}

			List<Map<String, Object>> orders = orderService.searchOrderByTypeNCode(args);

			model.addAttribute(Params.SUCCESS, orders == null ||orders.size()==0);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}

		return JsonView.NAME;
	}

	@RequestMapping(value = "/get-auth", method = { RequestMethod.POST })
	public String getDeleteAuth(Model model, HttpServletRequest request, @RequestParam String v) throws Exception {

		if (SecurityUtils.isGranted("ORDER_MAINTAIN")) {
			
			if(passwordEncoder.matches(v, SecurityUtils.getUser().getPassword()))
				model.addAttribute(Params.SUCCESS, Boolean.TRUE);
			else
				model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		} else {
			model.addAttribute(Params.SUCCESS, Boolean.FALSE);
		}
		return JsonView.NAME;
	}


}
