package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPartContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsInContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.StringJoiner;

/**
 * @Description : 验证加工单数量后保存加工结果工步
 * @Author : wangjie
 **/
@Slf4j
@Service("mesProductionDataSaveBeforeLockOrderStepService")
public class MesProductionDataSaveBeforeLockOrderStepService extends BaseStepService {

    @Autowired
    private IMesProductionProcessContextStepService productionProcessContextStepService;

    @Autowired
    private IMesProductionDispatchContextStepService productionDispatchContextStepService;

    @Autowired
    private MesWorkOrderCheckCompleteQtyStepService workOrderCheckCompleteQtyStepService;

    @Override
    public StepResult execute(StationRequestBean reqBean) {

        StationResultBean resultBean = new StationResultBean();

        StepResult stepResult = StepResult.getSuccessComplete();

        //获取上下文信息: 处理加工不可用规则
        MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchProdRuleIgnoreCfgContext(reqBean);

        //配置错误 抛出异常
        if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());

        //存储生产过程上下文对象
        productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext);

        //获取上下文产出零件数据信息集合
        List<MesProductionPartContext> productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean);

        //获取上下文进料零件条码信息集合
        List<MesProductionPsInContext> productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean);

        synchronized (new StringJoiner(MesPcnExtConstWords.COLON).add(reqBean.getOrganizeCode()).add(reqBean.getWorkCenterCode()).add(MesPcnExtConstWords.WORK_ORDER_COMPLETE_CONTEXT).toString().intern()) {

            //验证加工单完成数量
            workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext(
                    reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList);

            //匹配失败需要清除本次扫描/读取信息
            if (!stepResult.isCompleted() && workOrderCheckCompleteQtyStepService.doBusiCheckToDelete(reqBean, stepResult, productionPartContextList, productionPsInContextList))
                return stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_PART_NO);

            //非排序线 保存加工结果工步 execute 方法 使用的是 新事务
            stepResult = ((IStepService) SpringContextsUtil.getBean("mesProductionDataSaveStepService")).execute(reqBean);

            //保存加工结果事务提交之后, 保存工单计数
            if (stepResult.isCompleted() && !StringUtils.isEmpty(stepResult.getStepAfterState())) {
                IStepService stepService = ((IStepService) SpringContextsUtil.getBean(stepResult.getStepAfterState()));
                stepResult.stepAfterState(null);
                stepService.executeStepAfterExecute(reqBean, stepResult);
            }

        }

        return stepResult;

    }

}
