using Edu.AOP.CustomerAttribute;
using Edu.Cache.User;
using Edu.Common;
using Edu.Common.Enum.Course;
using Edu.Common.Enum.EduTask;
using Edu.Common.Enum.Finance;
using Edu.Common.Plugin;
using Edu.Model.Entity.Contract;
using Edu.Model.Entity.Course;
using Edu.Model.Entity.EduTask;
using Edu.Model.Entity.Sell;
using Edu.Model.ViewModel.Contract;
using Edu.Model.ViewModel.Course;
using Edu.Model.ViewModel.EduTask;
using Edu.Model.ViewModel.Grade;
using Edu.Model.ViewModel.Sell;
using Edu.Module.Course;
using Edu.Repository.Contract;
using Edu.Repository.Course;
using Edu.Repository.EduTask;
using Edu.Repository.Grade;
using Edu.Repository.Log;
using Edu.Repository.Sell;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using VT.FW.DB;

namespace Edu.Module.EduTask
{
    /// <summary>
    /// 订单转班、分拆处理类
    /// </summary>
    public class OrderChangeModule
    {
        /// <summary>
        /// 订单转班、分拆仓储层对象
        /// </summary>
        private readonly RB_Order_ChangeRepository order_ChangeRepository = new RB_Order_ChangeRepository();

        /// <summary>
        /// 教务单据仓储层对象
        /// </summary>
        private readonly RB_Education_ReceiptRepository education_ReceiptRepository = new RB_Education_ReceiptRepository();

        /// <summary>
        /// 订单仓储层对象
        /// </summary>
        private readonly RB_OrderRepository orderRepository = new RB_OrderRepository();

        /// <summary>
        /// 班级仓储层对象
        /// </summary>
        private readonly RB_ClassRepository classRepository = new RB_ClassRepository();

        /// <summary>
        /// 课程仓储层对象
        /// </summary>
        private readonly RB_CourseRepository courseRepository = new RB_CourseRepository();

        /// <summary>
        /// 订单处理类对象
        /// </summary>
        private readonly OrderModule orderModule = new OrderModule();

        /// <summary>
        /// 课程签到记录表
        /// </summary>
        private readonly RB_Class_CheckRepository classCheckRepository = new RB_Class_CheckRepository();

        /// <summary>
        /// 订单学员仓储层对象
        /// </summary>
        private readonly RB_Order_GuestRepository guestRepository = new RB_Order_GuestRepository();

        /// <summary>
        /// 用户日志
        /// </summary>
        private readonly RB_User_ChangeLogRepository changeLogRepository = new RB_User_ChangeLogRepository();

        /// <summary>
        /// 上课计划+上课时间仓储对象
        /// </summary>
        private readonly RB_Class_PlanRepository class_PlanRepository = new RB_Class_PlanRepository();

        /// <summary>
        /// 合同仓储层对象
        /// </summary>
        private readonly RB_Education_ContractRepository education_ContractRepository = new RB_Education_ContractRepository();

        /// <summary>
        /// 订单拆分仓储层对象
        /// </summary>
        private readonly RB_Order_SplitDetailsRepository splitDetailsRepository = new RB_Order_SplitDetailsRepository();

        /// <summary>
        /// 新增订单转班
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [TransactionCallHandler]
        public virtual bool SetOrderChangeModule(RB_Order_Change_ViewModel model,string receiptFile, out string message)
        {
            message = "";
            bool flag = false;
            var newId = order_ChangeRepository.Insert(model);
            model.Id = newId;
            flag = newId > 0;
            if (flag)
            {
                var educationReceipt = new RB_Education_Receipt()
                {
                    Id = 0,
                    Title = "订单转班申请",
                    ReceiptType = Common.Enum.Finance.ReceiptTypeEnum.OrderTransClass,
                    RelationId = newId,
                    OrderId = model.SourceOrderId,
                    ClassId = model.NewClassId,
                    Group_Id = model.Group_Id,
                    School_Id = model.School_Id,
                    CreateBy = model.CreateBy,
                    CreateTime = model.CreateTime,
                    UpdateBy = model.UpdateBy,
                    UpdateTime = model.UpdateTime,
                    VerifyStatus = Common.Enum.EduTask.EduTaskRrocessStatus.NotAudit,
                    IsCreate = 0,
                    EffectiveDate = model.EffectiveDate,
                    ReceiptFile= receiptFile
                };
                flag = education_ReceiptRepository.SetEducationReceiptRepository(educationReceipt, out message);
                Dictionary<string, object> guestFileds = new Dictionary<string, object>()
                {
                    {nameof(RB_Order_Guest_ViewModel.GuestState),(int)GuestStateEnum.TransferClassesApplyIng}
                };
                if (flag)
                {
                    flag = guestRepository.Update(guestFileds, new WhereHelper(nameof(RB_Order_Guest_ViewModel.Id), model.OrderGuestId));
                }
            }
            return flag;
        }

        /// <summary>
        /// 学员完成学习分钟数
        /// </summary>
        /// <param name="guestIds">学员编号</param>
        /// <returns></returns>
        public GuestFinishMinute_ViewModel GetGuestFinishMinutesModule(string guestIds)
        {
            var model = classCheckRepository.GetGuestFinishMinutesRepository(guestIds)?.FirstOrDefault();
            if (model == null)
            {
                model = new GuestFinishMinute_ViewModel();
            }
            return model;
        }

        /// <summary>
        /// 计算当前时间到订单生效时间有效课时数
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public decimal GetClassPlanTimeHoursModule(int ClassId, string StartTime, string EndTime)
        {
            var list = class_PlanRepository.GetClassPlanListExtRepository(new RB_Class_Plan_ViewModel()
            {
                ClassId = ClassId,
                StartTime = StartTime,
                EndTime = EndTime
            });
            return list?.Sum(qitem => qitem.TimeHour) ?? 0;
        }

        /// <summary>
        /// 定时更新转班订单数据
        /// </summary>
        public void GetChangeOrderListModule()
        {
            var list = education_ReceiptRepository.GetEducationReceiptListRepository(new EducationReceiptQuery()
            {
                ReceiptType = (int)ReceiptTypeEnum.OrderTransClass,
                VerifyStatus = (int)EduTaskRrocessStatus.AuditThrough,
                QEffectiveDate = Common.ConvertHelper.FormatDate(DateTime.Now)
            });
            if (list != null && list.Count > 0)
            {
                foreach (var item in list)
                {
                    if (item.IsCreate == 0)
                    {
                        UpdateOrderChangeModule(item);
                    }
                }
            }
        }

        /// <summary>
        /// 订单转班处理类方法
        /// </summary>
        /// <returns></returns>
        public bool UpdateOrderChangeModule(RB_Education_Receipt receiptModel)
        {
            bool flag = false;
            if (receiptModel.RelationId > 0)
            {
                var orderChangeModel = order_ChangeRepository.GetEntity<RB_Order_Change_ViewModel>(receiptModel.RelationId);

                if (orderChangeModel != null && orderChangeModel.Id > 0)
                {
                    //if (orderChangeModel.EffectiveDate < DateTime.Now)
                    //{
                    //    return false;
                    //}
                    var oldOrderModel = orderRepository.GetEntity(orderChangeModel.SourceOrderId);
                    var classList = classRepository.GetClassListRepository(new RB_Class_ViewModel()
                    {
                        Q_ClassIds = orderChangeModel.NewClassId + "," + oldOrderModel.ClassId
                    });
                    var oldClassModel = classList?.Where(qitem => qitem.ClassId == oldOrderModel.ClassId)?.FirstOrDefault() ?? new RB_Class_ViewModel();
                    var newClassModel = classList?.Where(qitem => qitem.ClassId == orderChangeModel.NewClassId)?.FirstOrDefault() ?? new RB_Class_ViewModel();
                    var newCourseModel = courseRepository.GetEntity(orderChangeModel.NewCourseId);
                    var userInfo = UserReidsCache.GetUserLoginInfo(oldOrderModel.EnterID);
                    var guestClassHours = GetGuestFinishMinutesModule(orderChangeModel.OrderGuestId.ToString());

                    var guestModel = guestRepository.GetEntity(orderChangeModel.OrderGuestId);
                    //计算课时单价
                    //老订单应收
                    //单个人员的课时单价
                    var unitPrice = (oldOrderModel.Income + oldOrderModel.PlatformTax) / oldOrderModel.GuestNum / guestModel.TotalHours;
                    //单人已完成应收
                    var singleFinishPrice = Math.Round(guestClassHours.FinishClassHours * unitPrice, 2);
                    //单人应收
                    var singlePreferPrice = Math.Round(guestModel.TotalHours * unitPrice, 2);
                    //原订单应收=原订单应收-单人应收+单人完成
                    decimal oldPreferPrice = oldOrderModel.PreferPrice - singlePreferPrice + singleFinishPrice;
                    //新订单应收和退款一致
                    decimal newPreferPrice = singlePreferPrice - singleFinishPrice;
                    #region 生成新订单
                    var orderModel = new RB_Order_ViewModel()
                    {
                        OrderId = 0,
                        ClassId = orderChangeModel.NewClassId,//班级编号
                        GuestNum = 1,
                        OrderSource = oldOrderModel.OrderSource,
                        OrderType = oldOrderModel.OrderType,
                        Class_Price = newCourseModel.SellPrice,//单价
                        Unit_Price = newCourseModel.SellPrice,//成交单价
                        PreferPrice = newPreferPrice,//应收,
                        Income = 0,
                        HelpEnterId = 0,
                        GeneralOccupation = "",
                        EduOccupation = "",
                        SaleRemark = orderChangeModel.Remarks,//销售备注
                        SourceId = 0,
                        IsLessPrice = 0,
                        LessPrice = 0,
                        PerLessMoney=0,
                        DiscountMoney=0,
                        PerDiscountMoney=0,
                        OrderNature = oldOrderModel.OrderNature,
                        OldPreferPrice = newPreferPrice,//应收,
                        CourseId = orderChangeModel.NewCourseId,
                        StartClassHours = 0,
                        UpOrderId = 0,
                        VisitorReserveId = 0,
                        JoinType = Common.Enum.Sale.OrderJoinTypeEnum.TransOrder,
                        TargetJoinType = Common.Enum.Sale.OrderJoinTypeEnum.Normal,
                        EffectTime = orderChangeModel.EffectiveDate,
                    };
                    orderModel.SourceOrderId = orderChangeModel.SourceOrderId;
                    orderModel.Group_Id = userInfo.Group_Id;
                    orderModel.School_Id = userInfo.School_Id;
                    orderModel.Dept_Id = userInfo.DeptId;
                    orderModel.OrderForm = OrderFormEnum.Computer;
                    orderModel.EnterID = userInfo.Id;
                    orderModel.OrderState = OrderStateEnum.Normal;
                    orderModel.TradeWay = TradeWayEnum.OnLine;
                    orderModel.CreateBy = userInfo.Id;
                    orderModel.CreateTime = DateTime.Now;
                    orderModel.UpdateBy = userInfo.Id;
                    orderModel.UpdateTime = DateTime.Now;
                    orderModel.OldGuestId = orderChangeModel.OrderGuestId;
                    if (oldOrderModel.FirstOrderId ==0)
                    {
                        orderModel.FirstOrderId = oldOrderModel.OrderId;
                    }
                    else
                    {
                        orderModel.FirstOrderId = oldOrderModel.FirstOrderId;
                    }
                    flag = orderModule.SetClassOrderCommonModule(orderModel, userInfo, false, out string message, out _);
                    #endregion 

                    if (flag)
                    {
                        if (oldOrderModel.FirstOrderId > 0)
                        {
                            //添加关联记录
                            splitDetailsRepository.Insert(new RB_Order_SplitDetails()
                            {
                                OldOrderId = orderModel.FirstOrderId,
                                S_OrderId = oldOrderModel.OrderId,
                                S_JoinType = oldOrderModel.JoinType,
                                S_ClassId = oldOrderModel.ClassId,
                                T_OrderId = orderModel.OrderId,
                                T_JoinType = orderModel.JoinType,
                                T_ClassId = orderModel.ClassId,
                                CreateBy = orderModel.CreateBy,
                                CreateTime = DateTime.Now
                            });
                        }
                        #region 修改老订单 【目标订单和应收】
                        Dictionary<string, object> fileds = new Dictionary<string, object>()
                        {
                            {nameof(RB_Order_ViewModel.TargetOrderId),orderModel.OrderId },
                            {nameof(RB_Order_ViewModel.PreferPrice),oldPreferPrice },
                            {nameof(RB_Order_ViewModel.TargetJoinType),(int) Common.Enum.Sale.OrderJoinTypeEnum.TransOrder },
                            {nameof(RB_Order_ViewModel.FirstOrderId),orderModel.FirstOrderId },
                        };
                        flag = orderRepository.Update(fileds, new WhereHelper(nameof(RB_Order_ViewModel.OrderId), orderChangeModel.SourceOrderId));
                        #endregion

                        #region 修改老学员课时相关
                        Dictionary<string, object> guestFileds = new Dictionary<string, object>()
                        {
                             {nameof(RB_Order_Guest_ViewModel.TotalHours),guestClassHours.FinishClassHours },
                             {nameof(RB_Order_Guest_ViewModel.GuestState),(int)GuestStateEnum.Graduate },
                        };
                        if (flag)
                        {
                            flag = guestRepository.Update(guestFileds, new WhereHelper(nameof(RB_Order_Guest_ViewModel.Id), orderChangeModel.OrderGuestId));
                        }
                        #endregion

                        #region 新增老订单合同和新的转班合同
                        oldOrderModel.PreferPrice = oldPreferPrice;
                        var oldContract =education_ContractRepository.GetList(new RB_Education_Contract_ViewModel()
                        {
                            OrderId = orderChangeModel.SourceOrderId,
                            GuestId = orderChangeModel.OrderGuestId,
                            Status=-1,
                        }).Where(qitem => qitem.Status == 0 || qitem.Status == 1 || qitem.Status == 2)?.FirstOrDefault();
                        //创建老订单合同
                        CreateContract(oldOrderModel, newCourseModel, oldContract,  orderChangeModel.OrderGuestId);
                        //创建新订单合同
                        CreateContract(orderModel, newCourseModel, oldContract, orderModel.NewGuestId);
                        #endregion

                        #region 生成财务单据

                        if (flag)
                        {
                            var changeModel = new OrderChangeFinace()
                            {
                                ChangeType = 1,
                                InCome = newPreferPrice,
                                GuestId = guestModel.Id,
                                GuestName = guestModel.GuestName,
                                UserInfo = userInfo,
                                ClassId = oldOrderModel.ClassId,
                                ClassName = oldClassModel.ClassName,
                                Class_School_Id = oldClassModel.School_Id,
                                SName = oldClassModel.SchoolName,
                                OrderId = oldOrderModel.OrderId,
                            };
                            var RelevanceFrId = CreateExpenditure(changeModel, out string msg1);
                            var changeModel2 = new OrderChangeFinace()
                            {
                                ChangeType = 1,
                                InCome = newPreferPrice,
                                GuestId = orderModel.NewGuestId,
                                GuestName = guestModel.GuestName,
                                UserInfo = userInfo,
                                ClassId = orderModel.ClassId,
                                ClassName = newClassModel.ClassName,
                                Class_School_Id = newClassModel.School_Id,
                                SName = newClassModel.SchoolName,
                                OrderId = orderModel.OrderId,
                                ReFinanceId = RelevanceFrId
                            };
                            var InCome = CreateInCome(changeModel2, out string msg2);
                            flag = RelevanceFrId > 0 && InCome > 0;
                        }
                        #endregion
                    }

                    if (flag)
                    {
                        Dictionary<string, object> fileds = new Dictionary<string, object>()
                        {
                            {nameof(RB_Education_Receipt.IsCreate),1}
                        };
                        flag = education_ReceiptRepository.Update(fileds, new WhereHelper(nameof(RB_Education_Receipt.Id), receiptModel.Id));
                    }
                }
            }
            return flag;
        }

        /// <summary>
        /// 转班、分拆收入
        /// </summary>
        public int CreateInCome(OrderChangeFinace change, out string msg)
        {
            msg = "";
            #region 新增财务单据
            var detailList = new List<object>
            {
                new
                {
                    CostTypeId=533,
                    Number = 1,
                    OriginalMoney = change.InCome,
                    UnitPrice = change.InCome,
                    Remark = "学员【"+change.GuestName+"】收入"
                }
            };
            string Remark = "【" + (change.ClassName ?? "") + "】下,订单" + change.OrderId + " 客人" + (change.ChangeType == 1 ? "转班" : "分拆");
            var financeObj = new
            {
                BType = 1,
                AccountId = 72,
                IsPublic = 7,
                ClientType = 3659,
                CurrencyId = 1,
                change.GuestId,
                WBMoney = change.InCome,
                PayDate = DateTime.Now.ToString("yyyy-MM-dd"),
                TemplateId = 186,
                OrderSource = 17,
                OrderID = change.OrderId,
                TCIDList = new List<int>() { change.ClassId },
                OtherType = 0,
                change.ReFinanceId,
                CallBackReFrId = change.ReFinanceId,
                Remark,
                detailList,
                CreateBy = change.UserInfo.Id,
                RB_Branch_Id = change.Class_School_Id,
                RB_Depart_Id = change.UserInfo.DeptId,
                RB_Group_Id = change.UserInfo.Group_Id,
                RB_CreateByName = change.UserInfo.AccountName,
                RB_DepartName = change.UserInfo.DeptName,
                RB_BranchName = change?.SName ?? "",
                RB_GroupName = change.UserInfo.GroupName,
                FinanceType = 2,
                RemitterName = change.ChangeType == 1 ? "转班" : "分拆",
                TradeDate = Common.ConvertHelper.FormatDate(DateTime.Now),
                AccountNumber = Common.ConvertHelper.FormatDate(DateTime.Now),
            };
            string sign = EncryptionHelper.AesEncrypt(JsonHelper.Serialize(financeObj), Config.ReadConfigKey("FinanceKey"));
            var resultInfo = new
            {
                msg = sign
            };

            string apiResult = HttpHelper.HttpPost(Config.ReadConfigKey("IncomeFinanceApi"), JsonHelper.Serialize(resultInfo), "");
            JObject parmsJob = JObject.Parse(apiResult);
            string resultCode = parmsJob.GetStringValue("resultCode");
            int frid = parmsJob.GetInt("data", 0);
            if (resultCode == "1" && frid > 0)
            {
                //记录日志
                changeLogRepository.Insert(new Model.Entity.Log.RB_User_ChangeLog()
                {
                    Id = 0,
                    Type = 1,
                    CreateBy = change.UserInfo.Id,
                    CreateTime = DateTime.Now,
                    Group_Id = change.UserInfo.Group_Id,
                    LogContent = "生成学员" + (change.ChangeType == 1 ? "转班" : "分拆") + "财务单据【" + change.OrderId + "】",
                    School_Id = change.UserInfo.School_Id,
                    SourceId = 0
                });
            }
            else
            {
                string message = parmsJob.GetStringValue("message");
                LogHelper.Write("CreateInCome:" + message);
                msg += change.OrderId + "创建财务单据失败;";
            }
            #endregion
            return frid;
        }

        /// <summary>
        /// 转班、分拆支出
        /// </summary>
        /// <param name="change"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public int CreateExpenditure(OrderChangeFinace change, out string msg)
        {
            msg = "";
            #region 新增财务单据
            var detailList = new List<object>
            {
                new
                {
                    CostTypeId=533,
                    Number = 1,
                    OriginalMoney =change.InCome,
                    UnitPrice = change.InCome,
                    Remark = "学员【"+change.GuestName+"】转班支出"
                }
            };
            string Remark = "【" + (change.ClassName) + "】下,订单" + change.OrderId + " 学员" + (change.ChangeType == 1 ? "转班" : "分拆") + "支出!";
            var financeObj = new
            {
                IsPublic = 7,
                ClientType = 10,
                ClientID = 3659,
                CurrencyId = 1,
                change.GuestId,
                WBMoney = change.InCome,
                PayDate = DateTime.Now.ToString("yyyy-MM-dd"),
                TemplateId = 185,
                OrderSource = 17,
                OrderID = change.OrderId,
                TCIDList = new List<int>() { change.ClassId },
                OtherType = 0,
                Remark,
                detailList,
                CreateBy = change.UserInfo.Id,
                RB_Branch_Id = change.Class_School_Id,
                RB_Depart_Id = change.UserInfo.DeptId,
                RB_Group_Id = change.UserInfo.Group_Id,
                RB_CreateByName = change.UserInfo.AccountName,
                RB_DepartName = change.UserInfo.DeptName,
                RB_BranchName = change?.SName ?? "",
                RB_GroupName = change.UserInfo.GroupName,
                FinanceType = 2
            };
            string sign = EncryptionHelper.AesEncrypt(JsonHelper.Serialize(financeObj), Config.ReadConfigKey("FinanceKey"));
            var resultInfo = new
            {
                msg = sign
            };
            string apiResult = HttpHelper.HttpPost(Config.ReadConfigKey("PaymentFinanceApi"), JsonHelper.Serialize(resultInfo), "");
            JObject parmsJob = JObject.Parse(apiResult);
            string resultCode = parmsJob.GetStringValue("resultCode");
            int frid = parmsJob.GetInt("data", 0);
            if (resultCode == "1" && frid > 0)
            {
                //记录日志
                changeLogRepository.Insert(new Model.Entity.Log.RB_User_ChangeLog()
                {
                    Id = 0,
                    Type = 1,
                    CreateBy = change.UserInfo.Id,
                    CreateTime = DateTime.Now,
                    Group_Id = change.UserInfo.Group_Id,
                    LogContent = "生成学员" + (change.ChangeType == 1 ? "转班" : "分拆") + "财务单据【" + change.OrderId + "】",
                    School_Id = change.UserInfo.School_Id,
                    SourceId = 0
                });
            }
            else
            {
                string message = parmsJob.GetStringValue("message");
                LogHelper.Write("CreateExpenditure:" + message);
                msg += change.OrderId + "创建财务单据失败;";
            }
            #endregion
            return frid;
        }


        #region 分拆订单

        /// <summary>
        /// 新增订单拆分申请
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [TransactionCallHandler]
        public virtual bool SetOrderSplitModule(RB_Order_Change_ViewModel model,string receiptFile, out string message)
        {
            message = "";
            bool flag = false;
            var newId = order_ChangeRepository.Insert(model);
            model.Id = newId;
            flag = newId > 0;
            if (flag)
            {
                var educationReceipt = new RB_Education_Receipt()
                {
                    Id = 0,
                    Title = "订单分拆申请",
                    ReceiptType = Common.Enum.Finance.ReceiptTypeEnum.OrderSplitClass,
                    RelationId = newId,
                    OrderId = model.SourceOrderId,
                    ClassId = model.NewClassId,
                    Group_Id = model.Group_Id,
                    School_Id = model.School_Id,
                    CreateBy = model.CreateBy,
                    CreateTime = model.CreateTime,
                    UpdateBy = model.UpdateBy,
                    UpdateTime = model.UpdateTime,
                    VerifyStatus = Common.Enum.EduTask.EduTaskRrocessStatus.NotAudit,
                    IsCreate = 0,
                    EffectiveDate = model.EffectiveDate,
                    ReceiptFile= receiptFile
                };
                flag = education_ReceiptRepository.SetEducationReceiptRepository(educationReceipt, out message);
                //Dictionary<string, object> guestFileds = new Dictionary<string, object>()
                //{
                //    {nameof(RB_Order_Guest_ViewModel.GuestState),8}
                //};
                //if (flag)
                //{
                //    flag = guestRepository.Update(guestFileds, new WhereHelper(nameof(RB_Order_Guest_ViewModel.Id), model.OrderGuestId));
                //}
            }
            return flag;
        }

        /// <summary>
        /// 测试生成单据
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public bool TestUpdateOrderSplitModule(int Id,int Type)
        {
            var model = education_ReceiptRepository.GetEntity(Id);
            if (Type == 1)
            {
                return UpdateOrderChangeModule(model);
            }
            else
            {
                return UpdateOrderSplitModule(model);
            }
        }

        /// <summary>
        /// 订单分拆处理类方法
        /// </summary>
        /// <returns></returns>
        public bool UpdateOrderSplitModule(RB_Education_Receipt receiptModel)
        {
            bool flag = false;
            if (receiptModel.RelationId > 0)
            {
                var orderChangeModel = order_ChangeRepository.GetEntity<RB_Order_Change_ViewModel>(receiptModel.RelationId);
                if (orderChangeModel != null && orderChangeModel.Id > 0)
                {
                    //计算新班级课时数
                    var planList = class_PlanRepository.GetClassPlanListExtRepository(new RB_Class_Plan_ViewModel()
                    {
                        ClassId = orderChangeModel.NewClassId,
                        StartTime = Common.ConvertHelper.FormatDate(orderChangeModel.EffectiveDate)
                    });
                    //原订单实体
                    var oldOrderModel = orderRepository.GetEntity(orderChangeModel.SourceOrderId);
                    var classList = classRepository.GetClassListRepository(new RB_Class_ViewModel()
                    {
                        Q_ClassIds = orderChangeModel.NewClassId + "," + oldOrderModel.ClassId
                    });
                    //课程列表
                    var courseList = courseRepository.GetCourseListRepository(new RB_Course_ViewModel()
                    {
                        QCourseIds = orderChangeModel.NewCourseId + "," + oldOrderModel.CourseId
                    });
                    var oldClassModel = classList?.Where(qitem => qitem.ClassId == oldOrderModel.ClassId)?.FirstOrDefault() ?? new RB_Class_ViewModel();
                    var newClassModel = classList?.Where(qitem => qitem.ClassId == orderChangeModel.NewClassId)?.FirstOrDefault() ?? new RB_Class_ViewModel();
                    //新课程信息
                    var newCourseModel = courseList?.Where(qitem => qitem.CourseId == orderChangeModel.NewCourseId)?.FirstOrDefault() ?? new RB_Course_ViewModel();
                    //班级有效课时
                    var courseValidHourse = planList?.Sum(qitem => qitem.TimeHour) ?? 0;
                    if (courseValidHourse > newCourseModel.ClassHours)
                    {
                        courseValidHourse = newCourseModel.ClassHours;
                    }
                    //原课程信息
                    var oldCourseModel = courseList.Where(qitem => qitem.CourseId == oldOrderModel.CourseId)?.FirstOrDefault() ?? new RB_Course_ViewModel();

                    //新班级课程的应收
                    var newPreferPrice = Math.Round(newCourseModel.SellPrice / newCourseModel.ClassHours * courseValidHourse, 2);
                    //原业务员
                    var userInfo = UserReidsCache.GetUserLoginInfo(oldOrderModel.EnterID);
                    //原学员信息
                    var guestModel = guestRepository.GetEntity(orderChangeModel.OrderGuestId);

                    //原订单应收=原订单应收-新班级课程的应收
                    decimal oldPreferPrice = oldOrderModel.PreferPrice - newPreferPrice;

                    #region 生成新订单
                    var orderModel = new RB_Order_ViewModel()
                    {
                        OrderId = 0,
                        ClassId = orderChangeModel.NewClassId,//班级编号
                        GuestNum = 1,
                        OrderSource = oldOrderModel.OrderSource,
                        OrderType = oldOrderModel.OrderType,
                        Class_Price = newCourseModel.SellPrice,//单价
                        Unit_Price = newCourseModel.SellPrice,//成交单价
                        PreferPrice = newPreferPrice,//应收,
                        Income = 0,
                        HelpEnterId = 0,
                        GeneralOccupation = "",
                        EduOccupation = "",
                        SaleRemark = orderChangeModel.Remarks,//销售备注
                        SourceId = 0,
                        IsLessPrice = 0,
                        LessPrice = 0,
                        PerLessMoney=0,
                        DiscountMoney=0,
                        PerDiscountMoney=0,
                        OrderNature = oldOrderModel.OrderNature,
                        OldPreferPrice = newPreferPrice,//应收,
                        CourseId = orderChangeModel.NewCourseId,
                        StartClassHours = 0,
                        UpOrderId = 0,
                        VisitorReserveId = 0,
                        JoinType = Common.Enum.Sale.OrderJoinTypeEnum.SplitOrder,
                        TargetJoinType = oldOrderModel.JoinType,
                        EffectTime = orderChangeModel.EffectiveDate,
                        
                    };
                    orderModel.SourceOrderId = orderChangeModel.SourceOrderId;
                    orderModel.Group_Id = userInfo.Group_Id;
                    orderModel.School_Id = userInfo.School_Id;
                    orderModel.Dept_Id = userInfo.DeptId;
                    orderModel.OrderForm = OrderFormEnum.Computer;
                    orderModel.EnterID = userInfo.Id;
                    orderModel.OrderState = OrderStateEnum.Normal;
                    orderModel.TradeWay = TradeWayEnum.OnLine;
                    orderModel.CreateBy = userInfo.Id;
                    orderModel.CreateTime = DateTime.Now;
                    orderModel.UpdateBy = userInfo.Id;
                    orderModel.UpdateTime = DateTime.Now;
                    orderModel.OldGuestId = orderChangeModel.OrderGuestId;
                    orderModel.NewGuestTotalClassHours = Convert.ToInt32(courseValidHourse);
                    orderModel.SourceOrderId = orderChangeModel.SourceOrderId;
                    if (oldOrderModel.FirstOrderId == 0)
                    {
                        orderModel.FirstOrderId = oldOrderModel.OrderId;
                    }
                    else
                    {
                        orderModel.FirstOrderId = oldOrderModel.FirstOrderId;
                    }
                    flag = orderModule.SetClassOrderCommonModule(orderModel, userInfo, false, out string message, out _);
                    #endregion 

                    if (flag)
                    {
                        //添加关联记录
                        splitDetailsRepository.Insert(new RB_Order_SplitDetails()
                        {
                            OldOrderId = orderModel.FirstOrderId,
                            S_OrderId = oldOrderModel.OrderId,
                            S_JoinType = oldOrderModel.JoinType,
                            S_ClassId = oldOrderModel.ClassId,
                            T_OrderId = orderModel.OrderId,
                            T_JoinType = orderModel.JoinType,
                            T_ClassId = orderModel.ClassId,
                            CreateBy = orderModel.CreateBy,
                            CreateTime = DateTime.Now
                        });

                        #region 修改老订单 【目标订单和应收】
                        Dictionary<string, object> fileds = new Dictionary<string, object>()
                        {
                            {nameof(RB_Order_ViewModel.TargetOrderId),orderModel.OrderId },
                            {nameof(RB_Order_ViewModel.PreferPrice),oldPreferPrice },
                            {nameof(RB_Order_ViewModel.TargetJoinType),(int) Common.Enum.Sale.OrderJoinTypeEnum.SplitOrder },
                            {nameof(RB_Order_ViewModel.FirstOrderId),orderModel.FirstOrderId},
                        };
                        flag = orderRepository.Update(fileds, new WhereHelper(nameof(RB_Order_ViewModel.OrderId), orderChangeModel.SourceOrderId));
                        #endregion

                        #region 修改老学员课时相关
                        Dictionary<string, object> guestFileds = new Dictionary<string, object>()
                        {
                             {nameof(RB_Order_Guest_ViewModel.TotalHours),guestModel.TotalHours-courseValidHourse },
                        };
                        if (flag)
                        {
                            flag = guestRepository.Update(guestFileds, new WhereHelper(nameof(RB_Order_Guest_ViewModel.Id), orderChangeModel.OrderGuestId));
                        }
                        #endregion

                        #region 创建合同
                        var oldContract = education_ContractRepository.GetList(new RB_Education_Contract_ViewModel()
                        {
                            OrderId = orderChangeModel.SourceOrderId,
                            GuestId = orderChangeModel.OrderGuestId,
                            Status=-1,
                        }).Where(qitem => qitem.Status == 0 || qitem.Status == 1 || qitem.Status == 2)?.FirstOrDefault();
                        //生成老订单合同
                        CreateContract(oldOrderModel, oldCourseModel, oldContract, orderChangeModel.OrderGuestId);
                        //生成新订单合同
                        CreateContract(orderModel, oldCourseModel, oldContract, orderModel.NewGuestId);
                        #endregion

                        #region 生成财务单据

                        if (flag)
                        {
                            var change1 = new OrderChangeFinace()
                            {
                                ChangeType = 2,
                                InCome = newPreferPrice,
                                GuestId = guestModel.Id,
                                GuestName = guestModel.GuestName,
                                UserInfo = userInfo,
                                ClassId = oldOrderModel.ClassId,
                                ClassName = oldClassModel.ClassName,
                                Class_School_Id = oldClassModel.School_Id,
                                SName = oldClassModel.SchoolName,
                                OrderId = oldOrderModel.OrderId
                            };
                            var RelevanceFrId = CreateExpenditure(change1, out string msg1);
                            var change2 = new OrderChangeFinace()
                            {
                                ChangeType = 2,
                                InCome = newPreferPrice,
                                GuestId = orderModel.NewGuestId,
                                GuestName = guestModel.GuestName,
                                UserInfo = userInfo,
                                ClassId = orderModel.ClassId,
                                ClassName = newClassModel.ClassName,
                                Class_School_Id = newClassModel.School_Id,
                                SName = newClassModel.SchoolName,
                                OrderId = orderModel.OrderId,
                                ReFinanceId = RelevanceFrId,
                            };
                            var InCome = CreateInCome(change2, out string msg2);
                            flag = RelevanceFrId > 0 && InCome > 0;
                        }
                        #endregion
                    }

                    if (flag)
                    {
                        //Dictionary<string, object> fileds = new Dictionary<string, object>()
                        //{
                        //    {nameof(RB_Education_Receipt.IsCreate),1}
                        //};
                        //flag = education_ReceiptRepository.Update(fileds, new WhereHelper(nameof(RB_Education_Receipt.Id), receiptModel.Id));
                    }
                }
            }
            return flag;
        }
       
        #endregion

        /// <summary>
        /// 生成合同
        /// </summary>
        /// <returns></returns>
        public bool CreateContract(RB_Order order, RB_Course course, RB_Education_Contract_ViewModel contractModel, int guestId)
        {
            bool flag = false; 
            var guestModel = guestRepository.GetEntity(guestId);
            var newModel = new RB_Education_Contract()
            {
                Id = 0,
                CType = ContractTypeEnum.Train,
                OrderId = order.OrderId,
                GuestId = guestId,
                ContractNo = education_ContractRepository.CreateContractNumRepository(order.Group_Id, guestModel.School_Id),
                StudentName = guestModel.GuestName,
                StuBirth = contractModel.StuBirth,
                StuSex = contractModel.StuSex,
                StuAddress = contractModel.StuAddress,
                StuTel = contractModel.StuTel,
                StuEmail = contractModel.StuEmail,
                ParentName = contractModel.ParentName,
                ParentRelation = contractModel.ParentRelation,
                ParentTel = contractModel.ParentTel,
                ParentEmail = contractModel.ParentEmail,
                UrgentName = contractModel.UrgentName,
                UrgentRelation = contractModel.UrgentRelation,
                UrgentTel = contractModel.UrgentTel,
                GuardianIDCard = contractModel.GuardianIDCard,
                CourseName = course.CourseName,
                SchoolName = contractModel.SchoolName,
                SchoolPrincipal = contractModel.SchoolPrincipal,
                StartLevel = contractModel.StartLevel,
                CourseConsultant = contractModel.CourseConsultant,
                Payee = contractModel.Payee,
                FirstClassHours = guestModel.TotalHours,
                FirstCourseFee = order.PreferPrice,
                FirstBookFee = 0,
                FirstClassFee = 0,
                FirstDiscountMoney = 0,
                FirstMoney = order.PreferPrice,
                FirstPayDate = contractModel.FirstPayDate,
                SecondClassHours = 0,
                SecondCourseFee = 0,
                SecondBookFee = 0,
                SecondClassFee = 0,
                SecondDiscountMoney = 0,
                SecondMoney = 0,
                SecondPayDate = contractModel.SecondPayDate,
                ThirdClassHours = 0,
                ThirdCourseFee = 0,
                ThirdBookFee = 0,
                ThirdClassFee = 0,
                ThirdDiscountMoney = 0,
                ThirdMoney = 0,
                ThirdPayDate = contractModel.ThirdPayDate,
                CNYCaps = StringHelper.MoneyToUpper(order.PreferPrice.ToString()),
                Money = order.PreferPrice,
                Exam = contractModel.Exam,
                IsSupplement = contractModel.IsSupplement,
                Sign = contractModel.Sign,
                SignDate = contractModel.SignDate,
                GuardianSign = contractModel.GuardianSign,
                AuditDate = contractModel.AuditDate,
                AuditEmpId = contractModel.AuditEmpId,
                IsCompanySeal = contractModel.IsCompanySeal,
                SealDate = contractModel.SealDate,
                Group_Id = contractModel.Group_Id,
                School_Id = contractModel.School_Id,
                CreateBy = contractModel.CreateBy,
                CreateTime = DateTime.Now,
                UpdateBy = contractModel.UpdateBy,
                UpdateTime = contractModel.UpdateTime,
                Status = contractModel.Status,
                IsSystemUse = 1,
                SourceContractId = contractModel.Id
            };
            Dictionary<string, object> fileds = new Dictionary<string, object>()
            {
                {nameof(RB_Education_Contract.IsSystemUse),0 }
            };
            flag = education_ContractRepository.Update(fileds, new WhereHelper(nameof(RB_Education_Contract.Id), contractModel.Id));
            flag = education_ContractRepository.Insert(newModel) > 0;
            return flag;
        }

        /// <summary>
        /// 回归原班上课
        /// </summary>
        /// <returns></returns>
        public bool RegressSourceClassModule(int OrderId,out string message)
        {
            bool flag = false;
            message = "";
            var order = orderRepository.GetEntity(OrderId);
            if (order == null)
            {
                message = "未找到此订单";
                return false;
            }
            if (order.FirstOrderId <= 0)
            {
                message = "当前订单不是转班/分拆订单不能回归原班!";
                return false;
            }
            var oldOrder = orderRepository.GetEntity(order.FirstOrderId);
            if (oldOrder == null)
            {
                message = "原订单不是转班/分拆订单不能回归原班!";
                return false;
            }
            var orderguestList = guestRepository.GetOrderGuestListRepository(new RB_Order_Guest_ViewModel() {
                OrderIds = OrderId + "," + order.FirstOrderId
            });
            var oldGuest = orderguestList.Where(qitem=>qitem.OrderId==oldOrder.OrderId)?.FirstOrDefault()??new RB_Order_Guest_ViewModel ();
            var guest = orderguestList.Where(qitem => qitem.OrderId == order.OrderId)?.FirstOrDefault() ?? new RB_Order_Guest_ViewModel();
            var classList = classRepository.GetClassListRepository(new RB_Class_ViewModel()
            {
                Q_ClassIds = oldOrder.ClassId + "," + order.ClassId
            });

            var oldContract = education_ContractRepository.GetList(new RB_Education_Contract_ViewModel()
            {
                OrderId = oldOrder.OrderId,
                GuestId = oldGuest.Id,
                Status=-1,
            }).Where(qitem => qitem.Status == 0 || qitem.Status == 1 || qitem.Status == 2)?.FirstOrDefault();

            var newContract = education_ContractRepository.GetList(new RB_Education_Contract_ViewModel()
            {
                OrderId = order.OrderId,
                GuestId = guest.Id,
                Status=-1,
            }).Where(qitem => qitem.Status == 0 || qitem.Status == 1 || qitem.Status == 2)?.FirstOrDefault();

            var oldClassModel = classList?.Where(qitem => qitem.ClassId == oldOrder.ClassId)?.FirstOrDefault() ?? new RB_Class_ViewModel();
            var newClassModel = classList?.Where(qitem => qitem.ClassId == order.ClassId)?.FirstOrDefault() ?? new RB_Class_ViewModel();
            //原业务员
            var userInfo = UserReidsCache.GetUserLoginInfo(oldOrder.EnterID);
            if (guest.TotalHours != guest.CompleteHours)
            {
                //生成收支相抵单据
                //剩余课时
                var surplus = guest.TotalHours - guest.CompleteHours;
                var refundMoney = Math.Round(order.PreferPrice/ guest.TotalHours * surplus, 2);
           
                #region  更新学员课时
                //更新老订单学员课时
                Dictionary<string, object> oldGuestFileds = new Dictionary<string, object>()
                {
                    {nameof(RB_Order_Guest_Extend.TotalHours),oldGuest.TotalHours+surplus }
                };
                flag= guestRepository.Update(oldGuestFileds, new WhereHelper(nameof(RB_Order_Guest_Extend.Id), oldGuest.Id));

                //更新新订单学员课时
                Dictionary<string, object> newGuestFileds = new Dictionary<string, object>()
                {
                    {nameof(RB_Order_Guest_Extend.TotalHours),guest.CompleteHours },
                    {nameof(RB_Order_Guest_Extend.GuestState),(int)GuestStateEnum.Graduate}
                };
                flag = guestRepository.Update(newGuestFileds, new WhereHelper(nameof(RB_Order_Guest_Extend.Id), guest.Id));
                #endregion

                #region 更新订单应收
                Dictionary<string, object> oldOrderFileds = new Dictionary<string, object>()
                {
                    {nameof(RB_Order.PreferPrice),oldOrder.PreferPrice+refundMoney}
                };
                //更新原订单应收
                flag = orderRepository.Update(oldOrderFileds, new WhereHelper(nameof(RB_Order.OrderId), oldOrder.OrderId));

                Dictionary<string, object> newOrderFileds = new Dictionary<string, object>()
                {
                    {nameof(RB_Order.PreferPrice),order.PreferPrice-refundMoney},
                    {nameof(RB_Order.IsBackClass),1}
                };
                //更新新订单应收
                flag = orderRepository.Update(newOrderFileds, new WhereHelper(nameof(RB_Order.OrderId), order.OrderId));
                #endregion

                #region 更新合同课时和应收
                Dictionary<string, object> oldContractFileds = new Dictionary<string, object>()
                {
                    {nameof(RB_Education_Contract.FirstClassHours),guest.CompleteHours},
                    {nameof(RB_Education_Contract.FirstCourseFee),order.PreferPrice-refundMoney },
                    {nameof(RB_Education_Contract.FirstMoney),order.PreferPrice-refundMoney },
                    {nameof(RB_Education_Contract.Money), order.PreferPrice-refundMoney},
                    {nameof(RB_Education_Contract.CNYCaps), StringHelper.MoneyToUpper((order.PreferPrice-refundMoney).ToString()) }
                };
                flag = education_ContractRepository.Update(oldContractFileds, new WhereHelper(nameof(RB_Education_Contract.Id), oldContract.Id));
                Dictionary<string, object> newContractFileds = new Dictionary<string, object>()
                {
                    {nameof(RB_Education_Contract.FirstClassHours), oldGuest.TotalHours+surplus},
                    {nameof(RB_Education_Contract.FirstCourseFee),oldOrder.PreferPrice+refundMoney },
                    {nameof(RB_Education_Contract.FirstMoney),oldOrder.PreferPrice+refundMoney },
                    {nameof(RB_Education_Contract.Money), oldOrder.PreferPrice+refundMoney},
                    {nameof(RB_Education_Contract.CNYCaps), StringHelper.MoneyToUpper((oldOrder.PreferPrice+refundMoney).ToString()) }
                };
                flag = education_ContractRepository.Update(newContractFileds, new WhereHelper(nameof(RB_Education_Contract.Id), newContract.Id));
                #endregion

                var outlay = new OrderChangeFinace()
                {
                    ChangeType = 2,
                    ClassId = order.ClassId,
                    GuestId = guest.Id,
                    OrderId = order.OrderId,
                    GuestName = guest.GuestName,
                    InCome = refundMoney,
                    ClassName = newClassModel.ClassName,
                    Class_School_Id = newClassModel.School_Id,
                    ReFinanceId = 0,
                    SName = newClassModel.SchoolName,
                    UserInfo = userInfo
                };
                //生成支出财务单据
                var RelevanceFrId = CreateExpenditure(outlay, out string msg2);

                var income = new OrderChangeFinace()
                {
                    ChangeType = 2,
                    ClassId = oldOrder.ClassId,
                    GuestId = guest.Id,
                    OrderId = oldOrder.OrderId,
                    GuestName = guest.GuestName,
                    InCome = refundMoney,
                    ClassName = oldClassModel.ClassName,
                    Class_School_Id = oldClassModel.School_Id,
                    ReFinanceId = RelevanceFrId,
                    SName = oldClassModel.SchoolName,
                    UserInfo = userInfo
                };
                //生成收入财务单据
                CreateInCome(income, out string msg);
            }
            return flag;
        }
    }
}