package com.awspaas.user.apps.donenow_ctt.controller;

import com.actionsoft.bpms.bo.engine.BO;
import com.actionsoft.bpms.bpmn.engine.model.run.delegate.ProcessInstance;
import com.actionsoft.bpms.commons.database.RowMap;
import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.server.bind.annotation.Controller;
import com.actionsoft.bpms.server.bind.annotation.Mapping;
import com.actionsoft.bpms.util.DBSql;
import com.actionsoft.sdk.local.SDK;
import com.actionsoft.sdk.local.api.Logger;
import org.apache.commons.lang3.StringUtils;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@Controller
public class contractCostController {
    private static final Logger logger = SDK.getLogAPI().getLogger(contractCostController.class);//记录日志

    /**
     *  合同服务拣货单
     * @param uc
     * @param contractServiceId
     * @param warehouseProductId
     * @return
     * @throws SQLException
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.costServicepick")
    public ResponseObject costServicepick(UserContext uc, String contractServiceId, String warehouseProductId) throws SQLException {
        String contractCostId = DBSql.getString("SELECT ID FROM BO_EU_DNCTT_CONTRACT_COST WHERE IS_SERVICE_PRODUCT=1 AND SERVICE_ID=?", new Object[]{contractServiceId});
        return costPick(uc, contractCostId, warehouseProductId);
    }

    /**
     * 合同产品拣货单
     * @param uc
     * @param contractCostId
     * @param warehouseProductId
     * @return
     * @throws SQLException
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.costpick")
    public ResponseObject costPick(UserContext uc, String contractCostId, String warehouseProductId) throws SQLException {
        //创建拣货单

        BO newBO = new BO();
        newBO.set("CONTRACT_COST_ID", contractCostId);
        newBO.set("WAREHOUSE_PRODUCT_ID", warehouseProductId);

        BO warhouseProductBO = SDK.getBOAPI().get("BO_EU_DNIVT_WAREHOUSE_PRODUCT", warehouseProductId);

        newBO.set("PRODUCT_ID", warhouseProductBO.get("PRODUCT_ID"));
        newBO.set("WAREHOUSE_ID", warhouseProductBO.get("WAREHOUSE_ID"));

        int warehouseProductQuantity = ObjToInt(warhouseProductBO.getString("QUANTITY"));//库存数量
        logger.info("库存数量:" + warehouseProductQuantity);

        //可用库存
        int warehouseProductAvailableQuantity = ObjToInt(DBSql.getString("SELECT SUM(AVAILABLE) FROM VIEW_EU_DNINVT_PRODUCT_INVENTORY where ID=?", new Object[]{warehouseProductId}));
        logger.info("可用库存数量:" + warehouseProductAvailableQuantity);

        if (warehouseProductAvailableQuantity <= 0)
            return ResponseObject.newErrResponse("库存数量不足");

        if (warehouseProductQuantity <= 0)
            return ResponseObject.newErrResponse("库存数量不足");

        if (warehouseProductAvailableQuantity <= warehouseProductQuantity)//可用库存数量
            warehouseProductQuantity = warehouseProductAvailableQuantity;

        //全部拣货数量
        int contractCostQuantity = ObjToInt(SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_COST", contractCostId, "QUANTITY"));
        logger.info("合同产品数量:" + contractCostQuantity);

        //已拣货数量
        int contractProductPickQuantity = ObjToInt(DBSql.getString("SELECT SUM(QUANTITY) FROM BO_EU_DNCTT_CONTRACT_COST_PRODUCT WHERE CONTRACT_COST_ID=?  AND CLOSED=0", new Object[]{contractCostId}));
        logger.info("已拣货数量:" + contractProductPickQuantity);

        ProcessInstance processInstance = SDK.getProcessAPI().createBOProcessInstance("obj_5670df3b3d164682a9aded38bae2e1be", uc.getUID(), "合同产品拣货单");
        String binidid = processInstance.getId();
        newBO.setBindId(processInstance.getId());
        int quantity = contractCostQuantity - contractProductPickQuantity;//待拣货数量

        if (quantity <= 0) return
                ResponseObject.newErrResponse("无需拣货");

        if (quantity > warehouseProductQuantity) {
            newBO.set("PICK_QUANTITY", warehouseProductQuantity);
        } else {
            newBO.set("PICK_QUANTITY", quantity);
        }

        SDK.getBOAPI().create("BO_EU_DNCTT_CONTRACT_PRODUCT_PICK", newBO, processInstance, uc);

        ResponseObject ro = getPickSNList(uc, processInstance.getId(), warehouseProductId, newBO.get("PICK_QUANTITY", int.class));
        if (ro.isOk() && ro.getData() != null) {
            DBSql.update("UPDATE BO_EU_DNCTT_CONTRACT_PRODUCT_PICK SET PICKED_SNS=? WHERE BINDID=?", new Object[]{ro.getData().toString(), processInstance.getId()});
        }

        String url = SDK.getFormAPI().getFormURL("", uc.getSessionId(), binidid, "", 1, "", "", "");

        url = SDK.getPortalAPI().getPortalUrl() + "/r" + url.substring(1);

        ResponseObject responseObject = ResponseObject.newOkResponse();
        responseObject.setData(url);

        return responseObject;
    }

    /**
     * 将Object转换为int
     * @param obj
     * @return
     */
    private int ObjToInt(Object obj) {
        if (obj == null) return 0;

        String objStr = obj.toString();
        if (objStr.equals("")) return 0;
        //如果有小数点，只取整数
        if (objStr.contains(".")) {
            objStr = objStr.substring(0, objStr.indexOf("."));
        }
        return Integer.parseInt(objStr);
    }


    /**
     * 取消拣货
     * @param uc
     * @param costProductId
     * @return
     * @throws SQLException
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.costcanclepick")
    public ResponseObject costCanclePick(UserContext uc, String costProductId) throws SQLException {

        BO bo = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", costProductId);

        BO newBO = new BO();
        ProcessInstance processInstance = SDK.getProcessAPI().createBOProcessInstance("obj_a10ee583a11045d3b0f82f29b81ea1cd", uc.getUID(), "合同产品取消拣货单");

        String binidid = processInstance.getId();
        newBO.setBindId(processInstance.getId());
        newBO.set("PICK_QUANTITY", bo.get("QUANTITY"));
        newBO.set("CONTRACT_COST_ID", bo.get("CONTRACT_COST_ID"));
        newBO.set("WAREHOUSE_ID", bo.get("WAREHOUSE_ID"));
        newBO.set("PRODUCT_ID", DBSql.getString("SELECT PRODUCT_ID FROM BO_EU_DNCTT_CONTRACT_COST WHERE ID=?", new Object[]{bo.get("CONTRACT_COST_ID")}));
        newBO.set("COST_PRODUCT_ID", bo.getId());

        SDK.getBOAPI().create("BO_EU_DNCTT_CONTRACT_PRODUCT_CANCLEPICK", newBO, processInstance, uc);

        String url = SDK.getFormAPI().getFormURL("", uc.getSessionId(), binidid, "", 1, "", "", "");

        url = SDK.getPortalAPI().getPortalUrl() + "/r" + url.substring(1);

        ResponseObject responseObject = ResponseObject.newOkResponse();
        responseObject.setData(url);

        return responseObject;
    }

    /**
     * 移库
     * @param uc
     * @param costProductId
     * @return
     * @throws SQLException
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.TransferPro")
    public ResponseObject transferPro(UserContext uc, String costProductId) throws SQLException {

        BO bo = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", costProductId);

        BO newBO = new BO();
        ProcessInstance processInstance = SDK.getProcessAPI().createBOProcessInstance("obj_855e0ecd2a0e42dfaf45b3d1fff0c710", uc.getUID(), "合同产品移库单");

        String binidid = processInstance.getId();
        newBO.setBindId(processInstance.getId());
        newBO.set("QUANTITY", bo.get("QUANTITY"));
        newBO.set("CONTRACT_COST_ID", bo.get("CONTRACT_COST_ID"));
        newBO.set("WAREHOUSE_ID", bo.get("WAREHOUSE_ID"));
        newBO.set("PRODUCT_ID", DBSql.getString("SELECT PRODUCT_ID FROM BO_EU_DNCTT_CONTRACT_COST WHERE ID=?", new Object[]{bo.get("CONTRACT_COST_ID")}));
        newBO.set("COST_PRODUCT_ID", bo.getId());

        SDK.getBOAPI().create("BO_EU_CTT_CONTRACT_PRODUCT_TRANSFER", newBO, processInstance, uc);

        String url = SDK.getFormAPI().getFormURL("", uc.getSessionId(), binidid, "", 1, "", "", "");

        url = SDK.getPortalAPI().getPortalUrl() + "/r" + url.substring(1);

        ResponseObject responseObject = ResponseObject.newOkResponse();
        responseObject.setData(url);

        return responseObject;
    }

    /**
     * 获取拣货单序列号
     * @param uc
     * @param bindid
     * @param warehouseProductId
     * @param quantity
     * @return
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.getPickSNList")
    public ResponseObject getPickSNList(UserContext uc, String bindid, String warehouseProductId, Integer quantity) {
        //移除上次选择
        SDK.getBOAPI().removeByBindId("BO_EU_DNCTT_CONTRACT_PRODUCT_PICKSN", bindid);
        //库存数量
        RowMap stockMap = DBSql.getMap("SELECT * FROM BO_EU_DNIVT_WAREHOUSE_PRODUCT WHERE ID=?", new Object[]{warehouseProductId});
        //库存产品

        String OUT_RULE = DBSql.getString("SELECT OUT_RULE FROM BO_EU_DNIVT_PRODUCT WHERE ID=?", new Object[]{stockMap.getString("PRODUCT_ID")});
        //1031 FIFO先进先出  1032 LIFO后进先出
        List<RowMap> lotList = DBSql.getMaps("SELECT b.* FROM bo_eu_dnivt_warehouse_product a JOIN BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT b ON a.BINDID=b.BINDID WHERE b.QUANTITY>0 AND a.ID=? ORDER BY b.CREATEDATE " + (OUT_RULE != null && OUT_RULE.equals("1032") ? "DESC" : "ASC"), new Object[]{warehouseProductId});

        //已被拣货数量
        List<RowMap> pickList = DBSql.getMaps("SELECT a.* from BO_EU_DNCTT_CONTRACT_COST_PRODUCT a JOIN BO_EU_DNCTT_CONTRACT_COST b ON a.CONTRACT_COST_ID=b.ID WHERE a.WAREHOUSE_ID=? AND b.PRODUCT_ID=?", new Object[]{stockMap.getString("WAREHOUSE_ID"), stockMap.getString("PRODUCT_ID")});

        List<String> selectedSns = new ArrayList<>();//默认选择
        for (RowMap lotMap : lotList) {
            String lotSNs = lotMap.getString("SN");
            if (StringUtils.isNotBlank(lotSNs)) {
                List<String> lotsns = new ArrayList<>();//本批次允许拣货数量
                for (String SN : lotSNs.split(",")) {
                    boolean isPicked = false;
                    for (RowMap pickMap : pickList) {
                        String pickSNs = pickMap.getString("SN");
                        if (StringUtils.isBlank(pickSNs)) continue;
                        for (String pickSN : pickSNs.split(",")) {
                            if (SN.equals(pickSN)) {
                                //已被拣货
                                isPicked = true;
                                break;
                            }
                        }
                        if (isPicked) break;
                    }
                    if (!isPicked) {
                        lotsns.add(SN);
                    }
                }
                if (lotsns.size() > quantity)//允许挑选
                {
                    for (String sn : lotsns) {
                        BO bo = new BO();
                        bo.set("SN", sn);
                        bo.setBindId(bindid);
                        SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_PRODUCT_PICKSN", bo, uc);
                    }
                    quantity = 0;
                } else {
                    //全部拣货，不允许挑选
                    quantity -= lotsns.size();
                    selectedSns.addAll(lotsns);
                }
                if (quantity <= 0) break;
            } else {
                //没有序列号的
                int lotQuantity = lotMap.getInt("QUANTITY");//库存数量
                if (quantity > lotQuantity) {
                    quantity = quantity - lotQuantity;
                } else {
                    quantity = 0;
                }
            }
        }

        if (quantity > 0) {
            //超过最大拣货数量
            return ResponseObject.newErrResponse("超过最大拣货数量");
        }
        ResponseObject responseObject = ResponseObject.newOkResponse();
        responseObject.setData(StringUtils.join(selectedSns, ","));
        return responseObject;
    }


    /**
     * 重新关联采购单
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.reAssociatePurchaseOrder")
    public ResponseObject reAssociatePurchaseOrder(UserContext uc, String contractCostId) {
        BO orderProductBO = SDK.getBOAPI().query("BO_EU_DNIVT_ORDER_PRODUCT").addQuery("CONTRACT_COST_ID=", contractCostId).detail();//采购单

        if (orderProductBO == null) return ResponseObject.newErrResponse("未找到采购单");

        if (DBSql.getString("SELECT STATUS_ID FROM BO_EU_DNIVT_ORDER WHERE ID=?", new Object[]{orderProductBO.getString("ORDER_ID")}).equals("2150") == false) {
            return ResponseObject.newErrResponse("采购单未接收，请在全部产品接收后操作");
        }

        String sns = "";
        int orderQuantity = 0;
        String movePro = "";
        //判断是否被移动到其他仓库
        List<RowMap> lots = DBSql.getMaps("SELECT a.SN,a.QUANTITY,b.NAME,b.CATE_ID FROM BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT a JOIN BO_EU_DNIVT_WAREHOUSE b ON a.WAREHOUSE_ID=b.ID WHERE a.ORDER_PRODUCT_ID=?", new Object[]{orderProductBO.getId()});
        if (lots.size() > 0) {
            for (RowMap lot : lots) {
                String SN = lot.getString("SN");
                String NAME = lot.getString("NAME");
                int QUANTITY = lot.getInt("QUANTITY");
                int CATE_ID = lot.getInt("CATE_ID");
                if (CATE_ID != 2)//如果不在虚拟仓库，说明已经移库
                {
                    if (StringUtils.isNotBlank(SN))
                        movePro += "产品序列号：" + SN + "，数量：" + QUANTITY + "已被移动到仓库" + NAME + "，";
                    else movePro += "数量：" + QUANTITY + "已被移动到仓库" + NAME + "，";

                } else {
                    if (StringUtils.isNotBlank(SN)) sns = sns + "," + SN;
                    orderQuantity = orderQuantity + QUANTITY;
                }
            }
            if (StringUtils.isNotBlank(sns)) sns = sns + ",";
            if (orderQuantity <= 0) return ResponseObject.newErrResponse("采购单产品已全部关联，请勿重复操作！");

        } else {
            return ResponseObject.newErrResponse("采购单产品已全部关联，请勿重复操作！");
        }

        //已经存在的采购单产品
        List<BO> costProductList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_COST_PRODUCT").addQuery("ORDER_ID=", orderProductBO.getString("ORDER_ID")).addQuery("CONTRACT_COST_ID=", orderProductBO.getString("CONTRACT_COST_ID")).addQuery("CLOSED=", "0").list();

        for (BO costProductBO : costProductList) {
            int quantity = Integer.parseInt(costProductBO.get("QUANTITY").toString());
            String sn = costProductBO.getString("SN");
            if (StringUtils.isNotBlank(sns) && StringUtils.isNotBlank(sn)) {
                for (String s : sn.split(",")) {
                    sns = sns.replace("," + s + ",", ",");
                }
            }
            orderQuantity = orderQuantity - quantity;
        }

        if (orderQuantity <= 0) {
            return ResponseObject.newErrResponse("采购单产品已全部关联，本次操作无效！");
        }
        if (StringUtils.isNotBlank(sns)) sns = sns.substring(1, sns.length() - 1);

        //创建新的采购单产品
        BO newCostProductBO = costProductList.get(0);
        newCostProductBO.set("SN", sns);
        newCostProductBO.set("QUANTITY", orderQuantity);
        newCostProductBO.set("ID", StringUtils.EMPTY);

        ProcessInstance processInstance = SDK.getProcessAPI().createBOProcessInstance("obj_6bc913271069455abbd516c556b26d31", uc.getUID(), "合同产品物流管理");
        newCostProductBO.setBindId(processInstance.getId());
        SDK.getBOAPI().create("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", newCostProductBO, processInstance, uc);

        if (StringUtils.isNotBlank(movePro)) {
            return ResponseObject.newOkResponse("采购单产品已全部关联，但存在已移动的仓库产品，请重新关联！" + movePro);
        }

        return ResponseObject.newOkResponse();
    }

    /**
     * 产品配送
     * @param uc
     * @param bindid
     * @return
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.costProductShip")
    public ResponseObject costProductShip(UserContext uc, String bindid) {
        BO costProductBO = SDK.getBOAPI().getByProcess("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", bindid);

        if (costProductBO.getString("IS_SHIP").equals("2"))
            return ResponseObject.newErrResponse("该产品已配送，请勿重复操作！");

        //只有状态是“待配送”和“已拣货”才能进行配送
        if (!costProductBO.getString("STATUS_ID").equals("2157") && !costProductBO.getString("STATUS_ID").equals("2158"))
            return ResponseObject.newErrResponse("该产品状态不是待配送或已拣货，请勿操作！");

        costProductBO.set("IS_SHIP", "1");//待配送
        costProductBO.set("OLD_QUANTITY", costProductBO.get("QUANTITY"));
        costProductBO.set("SHIPPING_TYPE_ID", null);
        costProductBO.set("SHIPPING_SN", costProductBO.get("SN"));

        SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", costProductBO);

        String url = "./w?appId=com.awspaas.user.apps.donenow_ctt&msaAppId=com.awspaas.user.apps.donenow_ctt&sid=" + uc.getSessionId() + "&cmd=CLIENT_DW_FORM_OPENPAGE&bindid=" + bindid;
        ResponseObject responseObject = ResponseObject.newOkResponse();
        responseObject.setData(url);
        return responseObject;
    }

}
