package com.sunda.spmsweb.wmscontroller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmsweb.util.JWTUtil;
import com.sunda.spmswms.service.ISapDeliveryNoteLogService;
import com.sunda.spmswms.service.ISapPackageListService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * <p>
 * SAP装箱单表抬头 前端控制器
 * </p>
 *
 * @author Wayne
 * @since 2021-04-22
 */
@RestController
@RequestMapping("/sapPackageList")
@Api(tags = "装箱单/出库任务初始化", description = "装箱单/出库任务初始化")
public class SapPackageListController {

    @Autowired
    ISapPackageListService iSapPackageListService;

    @Autowired
    ISapDeliveryNoteLogService iSapDeliveryNoteLogService;

    @PostMapping("/getSapPackageList")
    @ApiOperation(value = "获取装箱单任务Page分页",notes = "获取装箱单任务\n" +
            "1.装箱单号为空时，默认查询所有跟用户相关的装箱单号，返回信息到前端；\n" +
            "2.装箱单号不为空时：\n" +
            "    2.1 首先在 SPMS 查询该装箱单数据，存在则返回该数据到前端；\n" +
            "    2.2 不存在时则实时向 SAP REST 请求一次箱单数据：\n" +
            "           SAP 返回错误则将错误信息返回给前端展示；\n" +
            "           SAP 实时返回装箱单信息，则将装箱单信息写入 SPMS 数据库。再执行一次查询返回信息到前端。")
    @RequiresPermissions("sapPackageList-getSapPackageList")
    public ResponseResult getSapPackageList(String werks, String whsLocationCode,  String packageList, String spmsStatus, String planLoadingDateStart, String planLoadingDateEnd, @RequestParam int pageNo, @RequestParam int pageSize){
        String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
        try {
            Page<Map<String, Object>> pageData = iSapPackageListService.getSapPackageListPage(userId, packageList, spmsStatus, planLoadingDateStart, planLoadingDateEnd, pageNo, pageSize, werks, whsLocationCode);
            return ResponseResult.success().add("sapPackageList", pageData);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("获取装箱单信息出错");
        }
    }

    @PostMapping("/getSapPackageListDtl")
    @ApiOperation(value = "获取装箱单任务明细",notes = "获取装箱单任务明细以及装箱单操作日志信息，备件包含箱码信息。" +
            "packageList=PL1001")
    @RequiresPermissions("sapPackageList-getSapPackageListDtl")
    public ResponseResult getSapPackageListDtl(String packageList, String goodsType){
        try {
            return ResponseResult.success()
                    .add("sapPackageListDtl", iSapPackageListService.getSapPackageListDtl(packageList, goodsType))
                    .add("sapPackageListLog", iSapDeliveryNoteLogService.getDocumentLogs(packageList));
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("获取装箱单信息出错");
        }
    }

    @PostMapping("/updateSapPackageList")
    @ApiOperation(value = "更新装箱单同时生成出库任务",notes = "更新装箱单同时生成出库任务\n" +
            "packageList 装箱单号；targetStatus 更新后状态；currentStatus 当前状态；三个参数都必输；\n" +
            "20210714——检查装箱单信息数据是否为能被拆分执行的正确数据，若为脏数据则返回错误信息;\n" +
            "I 上游数据是否准确判别逻辑如下：\n" +
            "1.装箱单没有明细行（目前没发生），系统提示错误；\n" +
            "2.装箱单明细 货物类型 字段为‘M’和‘X’以外的值 SAP_PACKAGE_LIST_DTL，系统提示错误（目前没发生）；\n" +
            "3.装箱单备件明细行，没有装箱明细箱码关系数据 SAP_PACKAGE_BOX，系统提示错误；\n" +
            "4.装箱单备件明细行，有装箱单明细箱码关系的情况下，再判断明细中的箱码在 箱码信息表 是否存在，不存在则系统提示错误（目前没发生）；\n" +
            "5.装箱单贸易货明细行，如果存在装箱单明细箱码关系 SAP_PACKAGE_BOX，系统提示错误；\n\n" +
            "II 装箱单更新拆分出库任务逻辑如下：\n" +
            "1.更新装箱单表头。更新前该装箱单状态必须为 0待处理，否则不让更新；\n" +
            "2.更新装箱单表表头状态为目标状态；\n" +
            "3.实时向SAP发出 REST 请求信息，告知该装箱单已开始处理请锁定不再更新；\n" +
            "4.更新装箱单明细表对应的行状态；\n" +
            "5.装箱单更新成功后，执行 generateWhsOutTask 方法，按 装柜地点、货物类型、柜序号、可装柜日期 四个维度拆分出库任务；\n" +
            "6.装箱单明细逐行遍历转换成出库任务：如果出库任务已经存在，则将该出库任务的 任务uuid 写入 装箱单明细对应行；" +
            "如果出库任务不存在，则新建一个出库任务，同时将 出库任务uuid 写入 装箱单明细对应行；\n" +
            "7.记录装箱单操作日志；\n" +
            "8.记录出库任务日志；")
    @RequiresPermissions("sapPackageList-updateSapPackageList")
    public ResponseResult updateSapPackageList(String packageList, String targetStatus, String currentStatus){
        String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
        /** 检查装箱单信息数据是否为能被拆分执行的正确数据，若为脏数据则返回错误信息 */
        ResponseResult checkResult = iSapPackageListService.checkSapPackageListCanBeSplit(packageList);
        if (checkResult.getCode() != 200){
            return checkResult;
        }
        try {
            int resp = iSapPackageListService.updateSapPackageList(userId, packageList, targetStatus, currentStatus);
            if (resp > 0){
                return ResponseResult.success().add("sapPackageList", iSapPackageListService.getSapPackageList(userId, packageList, null));
            }else {
                return ResponseResult.error("更新装箱单信息出错");
            }
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("更新装箱单信息出错");
        }
    }

    @PostMapping("/getSapPackageListDtlM")
    @ApiOperation(value = "获取装箱单实际结果详情-贸易货",notes = "贸易货卸货入库，根据装箱单号查询装箱单结果详情数据" +
            "packageList=PL00027371, 或 PL00027372")
    public ResponseResult getSapPackageListDtlM(String packageList){
        try {
            return ResponseResult.success().add("sapPackageListDtlM", iSapPackageListService.getSapPackageListDtlM(packageList));
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("获取装箱单详细信息出错");
        }
    }

    @PostMapping("/lockSapPackageList")
    @ApiOperation(value = "装箱单执行通知SAP上锁",notes = "装箱单执行通知SAP上锁" +
            "packageList=PL00027371, 或 PL00027372")
    public ResponseResult lockSapPackageList(String packageList){
        try {
            JSONObject doc = iSapPackageListService.lockSapPackageList(packageList);
            return ResponseResult.success()
                    .add("dataToSap", doc.getJSONObject("dataToSap"))
                    .add("sapReturnedData", doc.getJSONObject("sapReturnedData"));
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("装箱单上锁出错");
        }
    }


    @PostMapping("/getSapPackageListRest")
    @ApiOperation(value = "从SAP实时Rest请求箱单数据",notes = "从SAP实时Rest请求箱单数据\n" +
            "packageList=PL00027371, 或 PL00027372，PL00038154，仅展示给前端用户查看，不做数据库更新或存储。")
    public ResponseResult getSapPackageListRest(String packageList){
        String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
        try {
            return iSapPackageListService.getSapPackageListRest(packageList,userId);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage());
        }
    }

    @PostMapping("/checkSapPackageListCanBeSplit")
    @ApiOperation(value = "判断装箱单数据能否被拆分",notes = "判断装箱单数据能否被拆分\n" +
            "判断装箱单数据能否被拆分。\n" +
            "M SP00000100; X SP00000300; M+X SP00000450;")
    public ResponseResult checkSapPackageListCanBeSplit(String packageList){
        try {
            return iSapPackageListService.checkSapPackageListCanBeSplit(packageList);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage());
        }
    }
    
    @PostMapping("/openSapPackageList")
    @ApiOperation(value = "装箱单关闭后重新打开",notes = "装箱单关闭后重新打开\n" +
            "装箱单关闭后重新打开。\n" +
            "packageList=PL00027371")
    public ResponseResult openSapPackageList(String packageList){
        try {
        	String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
            return iSapPackageListService.openSapPackageList(packageList, userId);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage());
        }
    }
    
    @PostMapping("/getSapDataToCreatePackageList")
    @ApiOperation(value = "获取SAP装箱单数据在SPMS创建出库任务",notes = "获取SAP装箱单数据在SPMS创建出库任务\n" +
            "装柜工厂：werks=CN01\n" +
            "装柜仓库：whsLocationCode=1061\n" +
            "装箱单号：packageList=PL00027371\n" +
            "柜序号：cabinetSerialNumber=1\n" +
            "货物类型：goodsType=M\n")
    @RequiresPermissions("sapPackageList-getSapDataToCreatePackageList")
    public ResponseResult getSapDataToCreatePackageList(String werks, String whsLocationCode,  String packageList, String cabinetSerialNumber, String goodsType){
        String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
        try {
            return iSapPackageListService.getSapDataToCreatePackageList(userId, packageList, werks, whsLocationCode, cabinetSerialNumber, goodsType);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("创建装箱单信息出错"+e.getMessage());
        }
    }
    
    @PostMapping("/selectReceivingWerks")
    @ApiOperation(value = "根据装柜工厂获取收货主体、收货工厂",notes = "根据装柜工厂获取收货主体、收货工厂\n" +
    		"装柜工厂：werks=CN01\n" +
    		"装箱单号：packageList=PL00027371\n")
    public ResponseResult selectReceivingWerks(String werks, String packageList){
    	String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
    	try {
    		return iSapPackageListService.selectReceivingWerks(userId, packageList, werks);
    	}catch (Exception e){
    		e.printStackTrace();
    		return ResponseResult.error("获取收货主体收货工厂信息出错"+e.getMessage());
    	}
    }
    
//    @PostMapping("/updateSapPackageListPda")
//	@ApiOperation(value="PDA更新装箱单同时生成出库任务",notes = "PDA更新装箱单同时生成出库任务" +
//            "{\n" +
//            "  \"sapPackageList\": {\n" +
//            "    \"packageList\": \"装箱单号\"\n" +
//            "  },\n" +
//            "  \"sapPackageListDtl\": [\n" +
//            "    {\n" +
//            "      \"packageList\": \"装箱单号\",\n" +
//            "      \"bukrs\": \"GF50\",\n" +
//            "      \"cabinetModel\": \"40HQ\",\n" +
//            "      \"cabinetNumber\": \"\",\n" +
//            "      \"cabinetSerialNumber\": \"4\",\n" +
//            "      \"consignee\": \"GF50\",\n" +
//            "      \"goodsType\": \"X\",\n" +
//            "      \"item\": \"120\",\n" +
//            "      \"loadingWerks\": \"CN01\",\n" +
//            "      \"loadingWhsLocationCode\": \"1061\",\n" +
//            "      \"materialNo\": \"851000013\",\n" +
//            "      \"plannedPackingNumber\": \"2\",\n" +
//            "      \"plannedPackingQty\": \"2\",\n" +
//            "      \"receivingWerks\": \"GF51\",\n" +
//            "      \"shipper\": \"AE00\",\n" +
//            "      \"spmsItemNo\": \"1\",\n" +
//            "      \"spmsStatus\": \"0\",\n" +
//            "      \"packageCode\": \"BJ-1180119259-0303\",\n" +
//            "      \"basicUnit\": \"SET\",\n" +
//            "      \"packingUnit\": \"SET\",\n" +
//            "      \"unitSales\": \"SET\"\n" +
//            "    }\n" +
//            "  ]\n" +
//            "}", httpMethod = "POST")
//    public ResponseResult updateSapPackageListPda(@RequestBody JSONObject obj){
//        String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
//        if (!obj.containsKey("sapPackageList") || !obj.containsKey("sapPackageListDtl")) {
//        	return ResponseResult.error("操作出错，所传参数未包含头、行参数");
//        }
//        JSONObject sapPackageList = obj.getJSONObject("sapPackageList");
//        if (sapPackageList == null || StringUtils.isBlank(sapPackageList.getString("packageList"))) {
//        	return ResponseResult.error("操作出错，所传头参数未传装箱单号");
//        }
//        String packageList = sapPackageList.getString("packageList");
//        /** 检查装箱单信息数据是否为能被拆分执行的正确数据，若为脏数据则返回错误信息 */
//        ResponseResult checkResult = iSapPackageListService.checkSapPackageListCanBeSplit(packageList);
//        if (checkResult.getCode() != 200){
//            return checkResult;
//        }
//        try {
//            int resp = iSapPackageListService.updateSapPackageListByPda(userId, obj);
//            if (resp > 0){
//                return ResponseResult.success().add("sapPackageList", iSapPackageListService.getSapPackageList(userId, packageList, null));
//            }else {
//                return ResponseResult.error("更新装箱单信息出错");
//            }
//        }catch (Exception e){
//            e.printStackTrace();
//            return ResponseResult.error("更新装箱单信息出错");
//        }
//    }
    
    @PostMapping("/getSapPackageListByPda")
    @ApiOperation(value = "PDA获取备件并且行项目有箱码的装箱单任务",notes = "PDA获取备件并且行项目有箱码的装箱单任务\n" +
            "必填：状态spmsStatus，当前页pageNo，页码大小pageSize；\n" +
            "{\n" +
            "\t\"spmsStatus\": \"1\",\n" +
            "\t\"pageNo\": \"1\",\n" +
            "\t\"pageSize\": \"20\"\n" +
            "}", httpMethod = "POST")
    public ResponseResult getSapPackageListByPda(String werks, String whsLocationCode,  String packageList, String spmsStatus, String planLoadingDateStart, String planLoadingDateEnd, @RequestParam int pageNo, @RequestParam int pageSize){
        String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
        try {
            Page<Map<String, Object>> pageData = iSapPackageListService.getSapPackageListPageByPda(userId, packageList, spmsStatus, planLoadingDateStart, planLoadingDateEnd, pageNo, pageSize, werks, whsLocationCode);
            return ResponseResult.success().add("sapPackageList", pageData);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("获取装箱单信息出错");
        }
    }

}
