plan.drl 12.2 KB
package com.bsth.service.schedule.plan;

import org.joda.time.*;
import java.util.*;

import com.bsth.service.schedule.rules.plan.PlanCalcuParam_input;
import com.bsth.service.schedule.rules.plan.PlanResult;

import com.bsth.repository.schedule.TTInfoDetailRepository;
import com.bsth.repository.schedule.CarConfigInfoRepository;
import com.bsth.repository.schedule.EmployeeConfigInfoRepository;
import com.bsth.repository.LineRepository;
import com.bsth.repository.BusinessRepository;

import com.bsth.service.schedule.rules.shiftloop.ScheduleResult_output;
import com.bsth.service.schedule.rules.shiftloop.ScheduleResults_output;
import com.bsth.service.schedule.rules.ttinfo.TTInfoResult_output;
import com.bsth.service.schedule.rules.ttinfo.TTInfoResults_output;
import com.bsth.entity.Line;
import com.bsth.entity.Business;

import com.bsth.entity.schedule.CarConfigInfo;
import com.bsth.entity.schedule.EmployeeConfigInfo;
import com.bsth.entity.schedule.TTInfo;
import com.bsth.entity.schedule.TTInfoDetail;
import com.bsth.entity.schedule.SchedulePlanInfo;

import org.slf4j.Logger
import org.joda.time.format.DateTimeFormat
import org.apache.commons.lang3.StringUtils;


// 全局日志类(一般使用调用此规则的service类)
global Logger log;

global TTInfoDetailRepository tTInfoDetailRepository;
global CarConfigInfoRepository carConfigInfoRepository;
global EmployeeConfigInfoRepository employeeConfigInfoRepository;
global LineRepository lineRepository;
global BusinessRepository businessRepository;

// 输出
global PlanResult planResult;

function Map xlidParams(String xlid) {
    Map param = new HashMap();
    param.put("xl.id_eq", Integer.valueOf(xlid));
    return param;
}

function List ecList(EmployeeConfigInfoRepository repo, String ecids) {
    List<String> ids = Arrays.asList(ecids.split("-"));
    List rst = new ArrayList();
    for (int i = 0; i < ids.size(); i++) {
        rst.add(repo.findOne(Long.parseLong(ids.get(i))));
    }
    return rst;
}

function LocalTime fcsjTime(String fcsj) {
    if ("NULL".equals(fcsj)) {
        return null;
    }
    return LocalTime.parse(fcsj, DateTimeFormat.forPattern("HH:mm"));
}

function String ttInfoId_sd(Map map, DateTime sd) {
    TTInfoResult_output ttInfoResult_output = (TTInfoResult_output) map.get(sd);
    return ttInfoResult_output.getTtInfoId();
}

/*
    规则说明:
    根据循环规则输出,时刻表选择规则输出,组合计算排班明细
*/

//-------------------- 第一阶段、计算迭代数据 -----------------//
declare Loop_result
    xlId: String // 线路id

    ruleLoop: List // 每天分配的规则 List<ScheduleResult_output>

    ttInfoMapLoop_temp: Map // 每天分配的时刻表 Map<DataTime, Collection<TTInfoResult_output>>
    ttInfoMapLoop: Map // 每天分配的时刻表 Map<DataTime, TTInfoResult_output>
    ttInfoMap: Map // 总共用到的时刻表 Map<id, TTInfoResult_output>
end

rule "calcu_step1_Loop_result"
    salience 1000
    when
        $param: PlanCalcuParam_input($xlId: xlId)
    then
        Loop_result loop_result = new Loop_result();
        loop_result.setXlId($xlId);
        loop_result.setRuleLoop($param.getScheduleResults_output().getResults());

        loop_result.setTtInfoMapLoop(new HashMap());
        loop_result.setTtInfoMap(new HashMap());

        com.google.common.collect.Multimap ttInfoMap_temp =
                    (com.google.common.collect.Multimap)
                        $param.getTtInfoResults_output().getResults().get(
                            String.valueOf($xlId));

        loop_result.setTtInfoMapLoop_temp(ttInfoMap_temp.asMap());

        insert(loop_result);

//        log.info("calcu_step1_Loop_result");
end

rule "calcu_step2_loop_result"
    salience 1000
    no-loop
    when
        $param: PlanCalcuParam_input($xlId: xlId)
        $lr: Loop_result(xlId == $xlId)
        $sd: DateTime() from $lr.ttInfoMapLoop_temp.keySet()
    then
        // 当天时刻表只取第一张 TODO:
        Collection col = (Collection) $lr.getTtInfoMapLoop_temp().get($sd);
        Iterator iter = col.iterator();
        TTInfoResult_output ttInfo_result = (TTInfoResult_output) iter.next();
        $lr.getTtInfoMapLoop().put($sd, ttInfo_result);

        // 总共使用的时刻表
        $lr.getTtInfoMap().put(ttInfo_result.getTtInfoId(), ttInfo_result);

        update($lr);

//        log.info("calcu_step2_Loop_result");
end

//-------------------- 第二阶段、将时刻表班次,车辆配置,人员配置信息载入 -----------------//

//--------------- 车辆配置信息载入 -------------//
declare CarConfig_Wrap
    id: String // 车辆配置id(cast字符串-方便比较)

    self: CarConfigInfo // 原始数据
end

rule "calcu_CarConfig_Wrap"
    salience 800
    when
        $lr: Loop_result($xlId: xlId)
        $ccf: CarConfigInfo() from carConfigInfoRepository.findByXlId(Integer.parseInt($xlId))
    then
        CarConfig_Wrap carConfig_wrap = new CarConfig_Wrap();
        carConfig_wrap.setId(String.valueOf($ccf.getId()));
        carConfig_wrap.setSelf($ccf);

        insert(carConfig_wrap);

//        log.info("calcu_CarConfig_Wrap");
end

//--------------- 人员配置信息载入 --------------//
declare EmployeeConfig_Wrap
    id: String // 人员配置id(cast字符串-方便比较)

    self: EmployeeConfigInfo // 原始数据
end

rule "calcu_EmployeeConfig_Wrap"
    salience 800
    when
        $lr: Loop_result($xlId: xlId)
        $eci: EmployeeConfigInfo() from employeeConfigInfoRepository.findByXlId(Integer.parseInt($xlId))
    then
        EmployeeConfig_Wrap employeeConfig_wrap = new EmployeeConfig_Wrap();
        employeeConfig_wrap.setId(String.valueOf($eci.getId()));
        employeeConfig_wrap.setSelf($eci);

        insert(employeeConfig_wrap);

//        log.info("calcu_EmployeeConfig_Wrap");
end

//----------------- 时刻表班次信息载入 -----------------//
declare TTInfo_gid_stat
    xlId: String // 线路id(cast字符串-方便比较)
    ttInfoId: String // 时刻表id(cast字符串-方便比较)
    gid: String // 路牌id(cast字符串-方便比较)

    maxFcno: Integer // 最大发车顺序号

    fbTime: LocalTime // 分班时间
end

rule "calcu_TTInfo_gid_stat"
    salience 800
    when
        $lr: Loop_result($xlId: xlId)
        $ttInfoId: String() from $lr.getTtInfoMap().keySet()
        $gids: List() from accumulate ($ttd: TTInfoDetail() from tTInfoDetailRepository.findByTtinfoId(Long.parseLong($ttInfoId)), gidscount($ttd))
        $gid: String() from $gids
        $fbtime_str: String() from accumulate ($ttd: TTInfoDetail(lp.id.toString() == $gid) from tTInfoDetailRepository.findByTtinfoId(Long.parseLong($ttInfoId)), gidfbtime($ttd))
        $maxfcno: Double() from accumulate ($ttd: TTInfoDetail(lp.id.toString() == $gid) from tTInfoDetailRepository.findByTtinfoId(Long.parseLong($ttInfoId)), max($ttd.getFcno()))
    then
        TTInfo_gid_stat ttInfo_gid_stat = new TTInfo_gid_stat();
        ttInfo_gid_stat.setXlId($xlId);
        ttInfo_gid_stat.setTtInfoId($ttInfoId);
        ttInfo_gid_stat.setGid($gid);

        ttInfo_gid_stat.setMaxFcno($maxfcno.intValue());
        ttInfo_gid_stat.setFbTime(fcsjTime($fbtime_str));

        insert(ttInfo_gid_stat);

//        log.info("xlid={},ttid={},gid={},maxfcno={},fbtime={}",
//            $xlId, $ttInfoId, $gid, ttInfo_gid_stat.getMaxFcno(), ttInfo_gid_stat.getFbTime());

end

declare TTInfoDetail_Wrap
    xlId: String // 线路id(cast字符串-方便比较)
    ttInfoId: String // 时刻表id(cast字符串-方便比较)
    gid: String // 路牌id(cast字符串-方便比较)

    isFirstBc: Boolean = false // 是否是当前路牌的第一个班次
    isLastBc: Boolean = false // 是否是当前路牌的最后一个班次
    isFb: Boolean = false // 是否分班

    self: TTInfoDetail // 原始数据
end

rule "calcu_TTInfoDetail_Wrap"
    salience 800
    when
        $lr: Loop_result($xlId: xlId)
        $ttInfoId: String() from $lr.getTtInfoMap().keySet()
        $ttInfoStat: TTInfo_gid_stat(
            ttInfoId == $ttInfoId,
            $gid: gid, $maxFcno: maxFcno)
        $ttInfoDetail: TTInfoDetail(lp.id.toString() == $gid) from tTInfoDetailRepository.findByTtinfoId(Long.parseLong($ttInfoId))
    then
        TTInfoDetail_Wrap ttInfoDetail_wrap = new TTInfoDetail_Wrap();
        ttInfoDetail_wrap.setXlId($xlId);
        ttInfoDetail_wrap.setTtInfoId($ttInfoId);
        ttInfoDetail_wrap.setGid($gid);
        ttInfoDetail_wrap.setIsFirstBc(1 == $ttInfoDetail.getFcno());
        ttInfoDetail_wrap.setIsLastBc($maxFcno == $ttInfoDetail.getFcno());

        LocalTime fcsj = fcsjTime($ttInfoDetail.getFcsj());
        LocalTime fbsj = $ttInfoStat.getFbTime();
        ttInfoDetail_wrap.setIsFb(fbsj == null ? false : (fcsj.isEqual(fbsj) || fcsj.isAfter(fbsj)));

        ttInfoDetail_wrap.setSelf($ttInfoDetail);

        insert(ttInfoDetail_wrap);

//        log.info("xlid={},ttid={},gid={},isFirstBc={},isLastBc={},isFb={},fcsj={}",
//            $xlId, $ttInfoId, $gid,
//            ttInfoDetail_wrap.getIsFirstBc(),
//            ttInfoDetail_wrap.getIsLastBc(),
//            ttInfoDetail_wrap.getIsFb(),
//            $ttInfoDetail.getFcsj());
end

//-------------------- 第三阶段、合并计算SchedulePlanInfo -----------------//

rule "Calcu_SchedulePlanInfo"
    salience 600
    when
        $param: PlanCalcuParam_input($xlId: xlId)
        $lr: Loop_result(xlId == $xlId)
        $sro: ScheduleResult_output($sd: sd, $gid: guideboardId) from $lr.getRuleLoop()
        CarConfig_Wrap(id == $sro.carConfigId, $cc: self)
        TTInfoDetail_Wrap(
            ttInfoId == ttInfoId_sd($lr.getTtInfoMapLoop(), $sd),
            gid == $gid,
            $isFb: isFb, $isFirstBc: isFirstBc, $isLastBc: isLastBc,
            $ttInfoDetail: self
        )
    then
        // 线路
        Line xl = lineRepository.findOne(Integer.parseInt($xlId));

        SchedulePlanInfo schedulePlanInfo = new SchedulePlanInfo(
            xl,
            $sro,
            $ttInfoDetail,
            $isFb,
            $cc,
            ecList(employeeConfigInfoRepository, $sro.getEmployeeConfigId()),
            $param.getSchedulePlan(),
            $isFirstBc,
            $isLastBc
        );

        // 获取公司,分公司信息
        String gsbm = xl.getCompany();
        String fgsbm = xl.getBrancheCompany();
        Business gs = null;
        Business fgs = null;

        if (StringUtils.isNotEmpty(gsbm)) {
            Iterator<Business> businessIterator1 = businessRepository.findByBusinessCode(gsbm).iterator();
            if (businessIterator1.hasNext()) {
                gs = (Business) businessIterator1.next();
            }
        }
        if (StringUtils.isNotEmpty(gsbm) && StringUtils.isNotEmpty(fgsbm)) {
            Iterator<Business> businessIterator2 = businessRepository.findByUpCodeAndBusinessCode(gsbm, fgsbm).iterator();
            if (businessIterator2.hasNext()) {
                fgs = (Business) businessIterator2.next();
            }
        }

        if (gs != null) {
            schedulePlanInfo.setGsBm(gs.getBusinessCode());
            schedulePlanInfo.setGsName(gs.getBusinessName());
        }
        if (fgs != null) {
            schedulePlanInfo.setFgsBm(fgs.getBusinessCode());
            schedulePlanInfo.setFgsName(fgs.getBusinessName());
        }

        // 操作人,操作时间
        schedulePlanInfo.setCreateBy($param.getSchedulePlan().getCreateBy());
        schedulePlanInfo.setCreateDate($param.getSchedulePlan().getCreateDate());
        schedulePlanInfo.setUpdateBy($param.getSchedulePlan().getUpdateBy());
        schedulePlanInfo.setUpdateDate($param.getSchedulePlan().getUpdateDate());

        // result 输出
        planResult.getSchedulePlanInfos().add(schedulePlanInfo);

        log.info("gid={},ecid={},ttInfoId={}",
            $gid, ecList(employeeConfigInfoRepository, $sro.getEmployeeConfigId()),
            ttInfoId_sd($lr.getTtInfoMapLoop(), $sd));

end