using AutoFixture;
using Hotline.Api.Controllers;
using Hotline.Application.CallCenter;
using Hotline.Caching.Interfaces;
using Hotline.CallCenter.Calls;
using Hotline.FlowEngine.Notifications;
using Hotline.Identity.Accounts;
using Hotline.Identity.Roles;
using Hotline.Orders;
using Hotline.Settings;
using Hotline.Settings.Hotspots;
using Hotline.Share.Dtos.CallCenter;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Dtos.Order.Publish;
using Hotline.Share.Dtos.Snapshot;
using Hotline.Share.Dtos.TrCallCenter;
using Hotline.Share.Enums.CallCenter;
using Hotline.Share.Enums.FlowEngine;
using Hotline.Share.Enums.Order;
using Hotline.Share.Enums.Settings;
using Hotline.Share.Tools;
using Hotline.Tests.Dto;
using Hotline.Tests.Mock;
using Hotline.Tests.SqlSuger;
using Hotline.Users;
using Mapster;
using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Hotline.FlowEngine.Workflows;
using XF.Domain.Authentications;
using XF.Domain.Cache;
using XF.Domain.Exceptions;
using XF.Domain.Repository;
using Hotline.ThirdAccountDomainServices.Interfaces;
using Hotline.ThirdAccountDomainServices;
using Hotline.Snapshot.IRepository;

namespace Hotline.Tests.Controller;

public class OrderControllerTest : TestBase
{
    private readonly OrderController _orderController;
    private readonly IRepository<Hotspot> _hotspotRepository;
    private readonly IOrderRepository _orderRepository;
    private readonly OrderServiceMock _orderServiceMock;
    private readonly IRepository<OrderPublish> _orderPublishRepository;
    private readonly INotificationHandler<EndWorkflowNotify> _orderPublishEndWorkflowHandler;
    private readonly IOrderVisitRepository _orderVisitRepository;
    private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
    private readonly IRepository<SystemSetting> _systemSettingRepository;
    private readonly ISystemSettingCacheManager _systemSettingCacheManager;
    private readonly IRepository<CallNative> _callNativeRepository;
    private readonly IRepository<CallidRelation> _callIdRelationRepository;
    private readonly XingTangCallApplication _defaultCallApplication;
    private readonly ISqlSugarClient _capSqlClient;
    private readonly IIndustryRepository _industryRepository;
    private readonly IOrderSnapshotRepository _orderSnapshotRepository;
    private readonly ISystemLogRepository _systemLogRepository;
    private readonly IOrderVisitDomainService _orderVisitDomainService;
    private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
    private readonly IWorkflowDomainService _workflowDomainService;

    public OrderControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository,
        UserController userController, IRepository<Hotspot> hotspotRepository, OrderController orderController,
        IOrderRepository orderRepository, IServiceScopeFactory scopeFactory, IRepository<User> userRepository,
        OrderServiceMock orderServiceMock, IRepository<OrderPublish> orderPublishRepository,
        INotificationHandler<EndWorkflowNotify> orderPublishEndWorkflowHandler,
        IOrderVisitRepository orderVisitRepository, IRepository<SystemSetting> systemSettingRepository,
        ISystemSettingCacheManager systemSettingCacheManager, IRepository<CallNative> callNativeRepository,
        IRepository<CallidRelation> callIdRelationRepository, XingTangCallApplication defaultCallApplication,
        ISugarUnitOfWork<CapDbContext> capDbContext, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdService,
        IThirdAccountRepository thirdAccount, IIndustryRepository industryRepository, IOrderSnapshotRepository orderSnapshotRepository,
        ISystemLogRepository systemLogRepository, IOrderVisitDomainService orderVisitDomainService,
        IRepository<OrderVisitDetail> orderVisitDetailRepository, ISystemDicDataCacheManager systemDicDataCacheManager,
        IWorkflowDomainService workflowDomainService,
        ITypedCache<SystemSetting> cacheSettingData, ThirdAccounSupplierFactory thirdAccountDomainFactory, IServiceProvider serviceProvider)
        : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount,
            cacheSettingData, thirdAccountDomainFactory, serviceProvider)
    {
        _hotspotRepository = hotspotRepository;
        _orderController = orderController;
        _orderController.ControllerContext = new ControllerContext
        {
            HttpContext = new DefaultHttpContext()
        };
        _orderRepository = orderRepository;
        _orderServiceMock = orderServiceMock;
        _orderPublishRepository = orderPublishRepository;
        _orderPublishEndWorkflowHandler = orderPublishEndWorkflowHandler;
        _orderVisitRepository = orderVisitRepository;
        _systemSettingRepository = systemSettingRepository;
        _systemSettingCacheManager = systemSettingCacheManager;
        _callNativeRepository = callNativeRepository;
        _callIdRelationRepository = callIdRelationRepository;
        _defaultCallApplication = defaultCallApplication;
        _capSqlClient = capDbContext.Db;
        _industryRepository = industryRepository;
        _orderSnapshotRepository = orderSnapshotRepository;
        _systemLogRepository = systemLogRepository;
        _orderVisitDomainService = orderVisitDomainService;
        _orderVisitDetailRepository = orderVisitDetailRepository;
        _systemDicDataCacheManager = systemDicDataCacheManager;
        _workflowDomainService = workflowDomainService;
    }

    /// <summary>
    /// 创建工单时传入一个错误callId
    /// 验证: 
    /// 测试在延迟消息后会不会把工单测CallId修复成正确的CallId
    /// 推送的省上数据是否正确
    /// 测试修复后的CallId 再次保存功能, 能通过 systemLog 查询修复记录, 拦截工单保存
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task OrderCallIdRelevance_Test()
    {
        var callNo = DateTime.Now.ToString("yyyyMMddhhmmss") + "Flow";
        var inDto = _fixture.Build<CallNative>()
            .With(m => m.Id, Ulid.NewUlid().ToString())
            .With(m => m.CallNo, callNo)
            .With(m => m.Direction, ECallDirection.In)
            .With(m => m.IsDeleted, false)
            .Create();
        await _callNativeRepository.AddAsync(inDto);

        var inDto2 = _fixture.Build<CallNative>()
            .With(m => m.Id, Ulid.NewUlid().ToString())
            .With(m => m.Direction, ECallDirection.Out)
            .With(m => m.CallNo, callNo)
            .With(m => m.AudioFile, string.Empty)
            .With(m => m.IsDeleted, false)
            .Create();
        await _callNativeRepository.AddAsync(inDto2);
        var callOrder = new CallidRelation
        {
            Id = callNo,
            CallId = inDto2.Id,
        };
        await _callIdRelationRepository.AddAsync(callOrder, CancellationToken.None);

        SetZuoXi();
        var order = _orderServiceMock.CreateOrder(callNo)
            .办理到派单员()
            .GetCreateResult();
        order.ShouldNotBeNull();
        await _defaultCallApplication.OrderRelateCallHandlerAsync(order.Id, CancellationToken.None);
        var orderEntity = await _orderRepository.GetAsync(order.Id);
        orderEntity.ShouldNotBeNull();
        orderEntity.CallId.ShouldBe(inDto.Id);
        var query = _capSqlClient.Queryable<PublishedEntity>()
            .Where(m => m.Name == "hotline.call.connect.order" && m.Content.Contains(order.Id));
        var sql = query.ToSqlString();
        sql.Contains("id").ShouldBeFalse("字段大小写错误" + sql);
        var published = await query.FirstAsync();
        published.ShouldNotBeNull("推送数据不存在");
        var message = published.Content.FromJson<Message<PublishCallRecrodDto>>();
        message.Value.Order.ShouldNotBeNull("推送的工单信息为空");
        message.Value.Order.ProvinceNo.ShouldNotBeNull("省工单编号不能为空");
        message.Value.Order.No.ShouldBe(order.No, "推送的工单编号错误");

        try
        {
            order = _orderServiceMock.CreateOrder(callNo)
                .办理到派单员()
                .GetCreateResult();
        }
        catch (UserFriendlyException e)
        {
            e.FriendlyMessage.ShouldBe("来电已保存工单!");
        }
    }

    [Fact]
    public async Task Visit_Test()
    {
        SetZuoXi();
        var order = _orderServiceMock.CreateOrder()
            .办理到一级部门()
            .办理到二级部门(Set一级部门)
            .办理一级部门汇总(Set二级部门)
            .办理到归档(Set一级部门)
            .发布工单(SetZuoXi)
            .GetCreateResult();

        var visit = await _orderVisitRepository.Queryable()
            .Where(m => m.OrderId == order.Id)
            .FirstAsync();
        var visitDetaila = await _orderVisitDetailRepository.Queryable().Where(m => m.VisitId == visit.Id).ToListAsync();
        var visitDetail = visitDetaila.Adapt<List<VisitDetailDto>>();
        var smsReply = _orderVisitDomainService.GetVisitEvaluateByReplyTxt("0");
        visitDetail.ForEach(m =>
        {
            m.SeatEvaluate = ESeatEvaluate.DefaultSatisfied;
            m.OrgProcessingResults = smsReply.GetOrgProcessingResults(_systemDicDataCacheManager.VisitSatisfaction);
            m.OrgHandledAttitude = smsReply.GetOrgHandledAttitude(_systemDicDataCacheManager.VisitSatisfaction);
        });

        var callNo = DateTime.Now.ToString("yyyyMMddhhmmss") + "Flow";
        var inDto = _fixture.Build<CallNative>()
            .With(m => m.Id, Ulid.NewUlid().ToString())
            .With(m => m.CallNo, callNo)
            .With(m => m.Direction, ECallDirection.In)
            .With(m => m.IsDeleted, false)
            .Create();
        await _callNativeRepository.AddAsync(inDto);

        _systemLogRepository.Add("回访外呼已经接通", "", new CallRemarkDto { CallId = callNo, CallNumber = inDto.ToNo }.ToJson(), "", 1, visit.Id);
        var visitDto = new VisitDto
        {
            Id = visit.Id,
            IsPutThrough = true,
            VisitDetails = visitDetail
        };

        await _orderController.Visit(visitDto);
        var orderEntity = await _orderRepository.GetAsync(order.Id);
        orderEntity.OrgProcessingResults.ShouldNotBeNull();
    }

    /// <summary>
    /// 创建工单并派送给派单员
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task ToPaiDanYuan_Test()
    {
        SetZuoXi();
        var order = _orderServiceMock.CreateOrder()
            .办理到派单员()
            .GetCreateResult();
        order.ShouldNotBeNull();
    }

    /// <summary>
    /// 创建随手拍工单
    /// 验证随手拍工单是否能正常创建
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task OrderSnapshot_Test()
    {
        var industryItems = await _industryRepository.Queryable().Where(m => m.Name == "文化旅游").Select(d => new { d.Id, d.Name, }).ToListAsync();
        var industry = industryItems.First();

        SetZuoXi();
        var order = _orderServiceMock.CreateOrder(industryId: industry.Id, industryName: industry.Name)
            .办理到派单员()
            .办理到归档(SetPaiDanYuan, data =>
            {
                data.IsEvasive = true;
                data.IsInactively = true;
            })
            .GetCreateResult();
        var orderEntity = await _orderRepository.GetAsync(order.Id);
        orderEntity.ShouldNotBeNull();

        var snapshot = await _orderSnapshotRepository.GetAsync(m => m.Id == order.Id);
        snapshot.ShouldNotBeNull();
        snapshot.IndustryId.ShouldBe(industry.Id);
        snapshot.IndustryName.ShouldBe(industry.Name);
    }


    /// <summary>
    /// 验证中心直办工单归档后 自动发布
    /// 是否推诿, 是否不积极
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task AutoPublish_Test()
    {
        SetZuoXi();
        var order = _orderServiceMock.CreateOrder()
            .办理到派单员()
            .办理到归档(SetPaiDanYuan, data =>
            {
                data.IsEvasive = true;
                data.IsInactively = true;
            })
            .GetCreateResult();
        var publish = await _orderPublishRepository.GetAsync(m => m.No == order.No);
        publish.ShouldNotBeNull(order.No);
        var orderEntity = await _orderRepository.GetAsync(order.Id);
        orderEntity.ShouldNotBeNull();
        orderEntity.IsEvasive.ShouldBeTrue();
        orderEntity.IsInactively.ShouldBeTrue();
        orderEntity.Status.ShouldBe(EOrderStatus.Visited);
        orderEntity.OrgProcessingResults.ShouldNotBeNull();
        orderEntity.OrgProcessingResults.Key.ShouldBe("4");
        orderEntity.OrgProcessingResults.Value.ShouldBe("满意");
        orderEntity.SeatEvaluate.ShouldBe(ESeatEvaluate.Satisfied);
    }

    [Fact]
    public void Set一级部门_Test()
    {
        Set一级部门();
    }

    [Fact]
    public async Task IsStepUrgent_True_Test()
    {
        SetZuoXi();
        var order = _orderServiceMock.CreateOrder()
            .办理到派单员()
            .办理到归档(SetPaiDanYuan, data => data.IsStepUrgent = true, workflow =>
            {
                workflow.BusinessType = EBusinessType.DepartmentLeader;
                workflow.Opinion = "测试保存勾选紧急";
            })
            .GetCreateResult();
        order.ShouldNotBeNull();
        order.Id.ShouldNotBeNull();
        var orderDto = await _orderController.Get(order.Id);
        orderDto.IsStepUrgent.ShouldBeTrue();
        orderDto.IsStepUrgenText.ShouldBe("紧急");
    }

    /// <summary>
    /// 测试在办理的过程中能正确保存 
    /// 1.与市民电话联系
    /// 2.已赴现场处置
    /// 3.其他
    /// 4.其他原因
    /// 5.经办人
    /// 6.经办人电话
    /// 7.沟通时间
    /// 8.沟通地点
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task CreateOrder_Test()
    {
        SetZuoXi();
        var order = _orderServiceMock.CreateOrder()
            .办理到一级部门()
            .办理到二级部门(Set一级部门)
            .办理一级部门汇总(Set二级部门)
            .GetCreateResult();
        order.Id.ShouldNotBeNull();
        var orderEntity = await _orderRepository.GetAsync(order.Id);
        orderEntity.RealCommunicationAddress.ShouldNotBeNull();
        orderEntity.RealCommunicationTime.ShouldNotBeNull();
        orderEntity.RealContactLocale.ShouldNotBeNull();
        orderEntity.RealContactLocale.ShouldBe(true);
        orderEntity.RealHandlerName.ShouldNotBeNull();
        orderEntity.RealHandlerPhone.ShouldNotBeNull();
    }

    [Fact]
    public async Task GetOrderHandleTimeConfigByAcceptType_Test()
    {
        var result = await _orderController.GetOrderHandleTimeConfigByAcceptType(Share.Enums.FlowEngine.EFlowDirection.OrgToCenter, "10");
        result.Count.ShouldBe(1);
        result.TimeText.ShouldBe("1个工作日");
        result.TimeType.ShouldBe(ETimeType.WorkDay);
    }


    /// <summary>
    /// 测试取消发布功能
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task CancelOrderPublish_Test()
    {
        var system = await _systemSettingRepository.Queryable()
            .Where(m => m.Code == SettingConstants.CancelPublishOrderEnabled)
            .FirstAsync();
        system.SettingValue[0] = "true";
        await _systemSettingRepository.UpdateAsync(system);
        _systemSettingCacheManager.DelSystemSetting(SettingConstants.CancelPublishOrderEnabled);

        SetZuoXi();
        var order = _orderServiceMock.CreateOrder()
            .办理到派单员()
            .办理到归档(SetPaiDanYuan, data =>
            {
                data.IsEvasive = true;
                data.IsInactively = true;
            })
            .GetCreateResult();
        var publish = await _orderPublishRepository.GetAsync(m => m.No == order.No);
        publish.ShouldNotBeNull(order.No);
        var orderEntity = await _orderRepository.GetAsync(order.Id);
        orderEntity.ShouldNotBeNull();
        orderEntity.IsEvasive.ShouldBeTrue();
        orderEntity.IsInactively.ShouldBeTrue();

        await _orderController.PublishCancelAsync(new PublishCancelInDto { OrderPublishId = publish.Id });
        var visit = await _orderVisitRepository.GetAsync(m => m.OrderId == order.Id);
        var publishCount = await _orderPublishRepository.Queryable().Where(m => m.OrderId == order.Id && m.IsDeleted == false).CountAsync();
        publishCount.ShouldBe(0, "发布工单数据已经被删除, 应该是0条");
        visit.ShouldNotBeNull("回访信息不存在");
        visit.VisitState.ShouldBe(EVisitState.Visited, "回访状态应该是已回访");

        orderEntity = await _orderRepository.GetAsync(order.Id);
        orderEntity.Status.ShouldBe(EOrderStatus.Filed);
        var publishList = await _orderController.PublishOrderList(new QueryOrderPublishDto
        {
            PageSize = 1000,
            QuerySelf = true
        });

        publishList.Items.Any(m => m.Id == order.Id).ShouldBeTrue("工单发布列表中没有取消的工单");
        SetZuoXi();
        // 验证是否能非上次发布人员发布
        try
        {
            await _orderController.PublishOrder(new PublishOrderDto { Id = order.Id });
        }
        catch (UserFriendlyException e)
        {
            e.Message.Contains("您不能发布").ShouldBeTrue();
        }

        // 验证被取消前的发布人能否继续发布
        SetPaiDanYuan();
        var inDto = _fixture.Create<PublishOrderDto>();
        inDto.Id = order.Id;
        await _orderController.PublishOrder(inDto);
        var published = await _orderPublishRepository.Queryable().Where(m => m.OrderId == order.Id && m.IsDeleted == false).FirstAsync();
        published.ShouldNotBeNull();
        published.IsDeleted.ShouldBeFalse();
    }

    /// <summary>
    /// 工单批量标注
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task OrderSignBath_Test()
    {
        var inDto = new OrderSignBathInDto
        {
            IsSafetyDepartment = true,
            Remark = "单元测试标注",
            OrderIds = new List<string>()
        };
        inDto.OrderIds.Add(_orderServiceMock.CreateSnapshotOrder(SetWeiXin, "安全隐患").办理到工单标注(SetZuoXi).GetCreateResult().Id);
        inDto.OrderIds.Add(_orderServiceMock.CreateSnapshotOrder(SetWeiXin, "安全隐患").办理到工单标注(SetZuoXi).GetCreateResult().Id);
        Set班长();
        await _orderController.GetNextStepsWithRecommend(inDto.OrderIds.First());
        var result = await _orderController.OrderSignBathAsync(inDto);
        result.Contains("标注完成").ShouldBe(true);
    }

    /// <summary>
    /// 中心直接归档-自动发布后: 回访详情,部门办件结果没有(满意)问题;
    /// </summary>
    /// <returns></returns>
    [Fact]
    public async Task OrderVisitCentor_Test()
    {
        //ChangeAppScopeYiBin();
        //var order = _orderServiceMock.CreateOrder()
        //    .办理到归档()
        //    .GetCreateResult(); ;
        //var orgVisit = await _orderVisitDetailRepository.Queryable()
        //    .Where(m => m.VisitTarget == EVisitTarget.Org)
        //    .FirstAsync();
        //orgVisit.VisitContent.ShouldBe("满意");
    }

    #region 工单流程

    /// <summary>
    /// 工单从创建到归档完整流程
    /// </summary>
    [Fact]
    public async Task OrderHandleTest()
    {
        SetZuoXi();
        var flowInPaiDan = _orderServiceMock.CreateOrder()
            .办理到派单员();
        var orderInfo = flowInPaiDan.GetCreateResult();
        //todo check order 
        var order = await _orderRepository.GetAsync(orderInfo.Id);
        order.ShouldNotBeNull();
        order.Status.ShouldBe(EOrderStatus.Handling);
        order.WorkflowId.ShouldNotBeNull();
        var workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSteps: true, withTraces: true);
        workflow.ShouldNotBeNull();
        workflow.Status.ShouldBe(EWorkflowStatus.Runnable);
        var step = workflow.Steps.FirstOrDefault(d=>d.BusinessType == EBusinessType.Send);
        var trace = workflow.Traces.FirstOrDefault(d => d.BusinessType == EBusinessType.Send);
        step.ShouldNotBeNull();
        trace.ShouldNotBeNull();
        step.Status.ShouldBe(EWorkflowStepStatus.WaitForAccept);
        trace.Status.ShouldBe(EWorkflowStepStatus.WaitForAccept);
        step.FlowAssignType.ShouldBe(EFlowAssignType.User);
        trace.FlowAssignType.ShouldBe(EFlowAssignType.User);
        step.RoleId.ShouldNotBeNull();
        trace.RoleId.ShouldNotBeNull();

        var flowInLevelOne = flowInPaiDan.办理到一级部门(SetPaiDanYuan);
        orderInfo = flowInLevelOne.GetCreateResult();
        order = await _orderRepository.GetAsync(orderInfo.Id);
        order.ShouldNotBeNull();
        order.Status.ShouldBe(EOrderStatus.Handling);
        order.WorkflowId.ShouldNotBeNull();
        workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSteps: true, withTraces: true);
        workflow.ShouldNotBeNull();
        workflow.Status.ShouldBe(EWorkflowStatus.Runnable);
        step = workflow.Steps.FirstOrDefault(d=> d.Status == EWorkflowStepStatus.WaitForAccept);
        trace = workflow.Traces.FirstOrDefault(d=> d.Status == EWorkflowStepStatus.WaitForAccept);
        step.ShouldNotBeNull();
        trace.ShouldNotBeNull();
        step.BusinessType.ShouldBe(EBusinessType.Department);
        trace.BusinessType.ShouldBe(EBusinessType.Department);
        step.FlowAssignType.ShouldBe(EFlowAssignType.Org);
        trace.FlowAssignType.ShouldBe(EFlowAssignType.Org);
        step.HandlerOrgId.ShouldNotBeNull();
        trace.HandlerOrgId.ShouldNotBeNull();
        step.HandlerOrgId.CalcOrgLevel().ShouldBe(1);
        trace.HandlerOrgId.CalcOrgLevel().ShouldBe(1);

        var flowInLevelTwo = flowInLevelOne.办理到二级部门(Set一级部门);
        orderInfo = flowInLevelTwo.GetCreateResult();
        order = await _orderRepository.GetAsync(orderInfo.Id);
        order.ShouldNotBeNull();
        order.Status.ShouldBe(EOrderStatus.Handling);
        order.WorkflowId.ShouldNotBeNull();
        workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSteps: true, withTraces: true);
        workflow.ShouldNotBeNull();
        workflow.Status.ShouldBe(EWorkflowStatus.Runnable);
        step = workflow.Steps.FirstOrDefault(d=> d.Status == EWorkflowStepStatus.WaitForAccept);
        trace = workflow.Traces.FirstOrDefault(d=> d.Status == EWorkflowStepStatus.WaitForAccept);
        step.ShouldNotBeNull();
        trace.ShouldNotBeNull();
        step.BusinessType.ShouldBe(EBusinessType.Department);
        trace.BusinessType.ShouldBe(EBusinessType.Department);
        step.FlowAssignType.ShouldBe(EFlowAssignType.Org);
        trace.FlowAssignType.ShouldBe(EFlowAssignType.Org);
        step.HandlerOrgId.ShouldNotBeNull();
        trace.HandlerOrgId.ShouldNotBeNull();
        step.HandlerOrgId.CalcOrgLevel().ShouldBe(2);
        trace.HandlerOrgId.CalcOrgLevel().ShouldBe(2);

        var flowInLevelOneSummary = flowInLevelTwo.办理一级部门汇总(Set二级部门);
        orderInfo = flowInLevelOneSummary.GetCreateResult();
        order = await _orderRepository.GetAsync(orderInfo.Id);
        order.ShouldNotBeNull();
        order.Status.ShouldBe(EOrderStatus.Handling);
        order.WorkflowId.ShouldNotBeNull();
        workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSteps: true, withTraces: true);
        workflow.ShouldNotBeNull();
        workflow.Status.ShouldBe(EWorkflowStatus.Runnable);
        step = workflow.Steps.FirstOrDefault(d=> d.Status == EWorkflowStepStatus.WaitForAccept);
        trace = workflow.Traces.FirstOrDefault(d=> d.Status == EWorkflowStepStatus.WaitForAccept);
        step.ShouldNotBeNull();
        trace.ShouldNotBeNull();
        step.StepType.ShouldBe(EStepType.Summary);
        trace.StepType.ShouldBe(EStepType.Summary);
        step.BusinessType.ShouldBe(EBusinessType.Department);
        trace.BusinessType.ShouldBe(EBusinessType.Department);
        step.FlowAssignType.ShouldBe(EFlowAssignType.Org);
        trace.FlowAssignType.ShouldBe(EFlowAssignType.Org);
        step.HandlerOrgId.ShouldNotBeNull();
        trace.HandlerOrgId.ShouldNotBeNull();
        step.HandlerOrgId.CalcOrgLevel().ShouldBe(1);
        trace.HandlerOrgId.CalcOrgLevel().ShouldBe(1);

        var flowInEnd = flowInLevelOneSummary.办理到归档(Set一级部门);
        orderInfo = flowInEnd.GetCreateResult();
        order = await _orderRepository.GetAsync(orderInfo.Id);
        order.ShouldNotBeNull();
        order.Status.ShouldBe(EOrderStatus.Filed);
        order.FiledTime.ShouldNotBeNull();
        order.WorkflowId.ShouldNotBeNull();
        workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSteps: true, withTraces: true);
        workflow.ShouldNotBeNull();
        workflow.Status.ShouldBe(EWorkflowStatus.Completed);
        step = workflow.Steps.FirstOrDefault(d=> d.StepType == EStepType.End);
        trace = workflow.Traces.FirstOrDefault(d=> d.StepType == EStepType.End);
        step.ShouldNotBeNull();
        trace.ShouldNotBeNull();
        
        //
        // flowInEnd.发布工单(SetZuoXi)
        //     .GetCreateResult();
    }

    #endregion
}