protected override void OnSaving()
        {
            if (string.IsNullOrEmpty(this.届别))
            {
                throw new Exception("届别不能为空");
            }
            if (string.IsNullOrEmpty(this.岗位级别))
            {
                throw new Exception("岗位级别不能为空.");
            }
            if (string.IsNullOrEmpty(this.能力级别))
            {
                throw new Exception("能力级别不能为空.");
            }

            ManagementTraineePayRiseStandard found = GetManagementTraineePayRiseStandard(届别, 岗位级别, 类别, 能力级别, 提资序数);

            if (found != null && found.标识 != this.标识)
            {
                throw new Exception("已经存在该提资标准,不能重复创建");
            }
            else
            {
                base.OnSaving();
            }
        }
        private void InitTreeView()
        {
            int division_start = 2015;
            int division_end   = DateTime.Today.Year;

            //构造第二层目录
            foreach (TreeNode node in treeView1.Nodes)
            {
                string grade = node.Name;

                for (int division = division_start; division <= division_end; division++)
                {
                    TreeNode division_node = new TreeNode(division.ToString() + " 届");

                    if (CheckUseType())
                    {
                        //类别
                        string[] type_arr = GetTypeList(division, grade);
                        for (int i = 0; i < type_arr.Length; i++)
                        {
                            string         type = type_arr[i];
                            FormParameters fp   = new FormParameters();
                            fp.Parameters  = new object[] { division.ToString(), grade, type };
                            fp.Name        = command;
                            fp.Description = command;

                            TreeNode type_node = new TreeNode(type);
                            type_node.Tag = fp;
                            //如果是薪酬计划,先判断是否已经录入了,如果没有录入,不显示
                            if (command == "薪酬计划表" || command == "年薪提资周期及各次提幅标准表")
                            {
                                int count = ManagementTraineePayRiseStandard.Count(division.ToString(), grade, type);
                                if (count > 0)
                                {
                                    division_node.Nodes.Add(type_node);
                                }
                            }
                            else
                            {
                                division_node.Nodes.Add(type_node);
                            }
                        }
                    }
                    else
                    {
                        FormParameters fp = new FormParameters();
                        fp.Parameters  = new object[] { division.ToString(), grade };
                        fp.Name        = command;
                        fp.Description = command;

                        division_node.Tag = fp;
                    }
                    node.Nodes.Add(division_node);
                    node.Expand();
                }
            }
        }
        /// <summary>
        /// 创建或更新提资标准
        /// </summary>
        /// <param name="seq">序号</param>
        /// <param name="rise_rate">增幅</param>
        /// <param name="year_salary">年薪</param>
        /// <param name="rise_type">提资方式</param>
        private void CreateOrUpdatePayStandard(string level, int seq, decimal rise_rate, decimal year_salary, RiseType rise_type)
        {
            ManagementTraineePayRiseStandard m = ManagementTraineePayRiseStandard.AddManagementTraineePayRiseStandard(届别, 岗位级别, 类别, level, seq);

            m.序号   = 序号;
            m.增幅   = rise_rate;
            m.年薪   = year_salary;
            m.提资方式 = (int)rise_type;
            if (AccessController.CurrentUser != null)
            {
                m.创建人 = AccessController.CurrentUser.姓名;
            }
            m.Save();
        }
        //更新到正式表
        public void UpdateToFormalTable()
        {
            if (this.内容不同的字段.Count > 0)
            {
                return;
            }
            //清除旧记录
            ManagementTraineePayRiseStandard.Clear(届别, 岗位级别, 类别);
            //创建和更新提资标准
            CreateOrUpdatePayStandard();
            //更新生效标记
            if (!this.已生效)
            {
                this.生效时间 = DateTime.Now;
                this.Save();

                ManagementTraineePayRiseStandardInput opposite = 另一人录入的记录;
                opposite.生效时间 = DateTime.Now;
                opposite.Save();
            }
        }
        public static ManagementTraineePayRiseStandard AddManagementTraineePayRiseStandard(string division, string grade, string type, string level, int seq)
        {
            ManagementTraineePayRiseStandard item = GetManagementTraineePayRiseStandard(division, grade, type, level, seq);

            if (item == null)
            {
                item = new ManagementTraineePayRiseStandard();

                item.标识   = Guid.NewGuid();
                item.届别   = division;
                item.岗位级别 = grade;
                item.类别   = type;
                item.能力级别 = level;
                item.提资序数 = seq;
                item.创建时间 = DateTime.Now;

                //提资周期
                switch (level)
                {
                case "A":
                    item.提资周期 = "6个月";
                    break;

                case "B":
                    item.提资周期 = "9个月";
                    break;

                case "C":
                    item.提资周期 = "12个月";
                    break;
                }

                item.Save();
            }

            return(item);
        }
        public static List <ManagementTraineeSalaryPlan> GeneratePlanList(string division, string grade, string type, string level)
        {
            List <ManagementTraineeSalaryPlan> planList = new List <ManagementTraineeSalaryPlan>();

            int year_count    = ManagementTraineePayStandard.GetStepStartYear(division, grade, type, -1);
            int quarter_total = year_count * 4;

            List <ManagementTraineePayRiseStandard> standards = ManagementTraineePayRiseStandard.GetManagementTraineePayRiseStandardList(division, grade, type, level);

            int[] rise_flag_a_arr = new int[] {
                0, 0, 1, 0, //第一年
                1, 0, 1, 0, //第二年
                1, 0, 1, 0, //第三年
                1, 0, 1, 0, //第四年
                1, 0, 1, 0, //第五年
                1, 0, 1, 0, //第六年
                1, 0, 0, 0  //第七年
            };
            int[] rise_flag_b_arr = new int[] {
                0, 0, 1, 0, //第一年
                1, 0, 0, 1, //第二年
                0, 0, 1, 0, //第三年
                0, 1, 0, 0, //第四年
                1, 0, 0, 1, //第五年
                0, 0, 1, 0, //第六年
                1, 0, 0, 0  //第七年
            };

            int[] rise_flag_c_arr = new int[] {
                0, 0, 1, 0, //第一年
                1, 0, 0, 0, //第二年
                1, 0, 0, 0, //第三年
                1, 0, 0, 0, //第四年
                1, 0, 0, 0, //第五年
                1, 0, 0, 0, //第六年
                1, 0, 0, 0  //第七年
            };

            int     time             = 0; //提资序数
            decimal last_year_salary = 0; //上一期年薪

            for (int i = 0; i < quarter_total; i++)
            {
                bool riseFlag = false; //提资标记
                //获取当前季度所处的节点
                double step = ManagementTraineePayStandard.GetStep(division, grade, type, i);

                if (level == "A")
                {
                    riseFlag = rise_flag_a_arr[i] == 1;
                }
                if (level == "B")
                {
                    riseFlag = rise_flag_b_arr[i] == 1;
                }
                if (level == "C")
                {
                    riseFlag = rise_flag_c_arr[i] == 1;
                }

                if (step < 1 && step != 0)
                {
                    riseFlag = false;
                }
                if (riseFlag && time < 10000)
                {
                    time++;                           //如果提资,序数+1
                }
                //升阶(满足升阶条件,先升阶,每阶+100, 满阶是 10000)
                //2018-9-21 进入二阶段以后,达到也要达到提资时间间隔才能提资
                if (step >= 2 && time < 100 && riseFlag)
                {
                    time = 100;
                }
                if (step == 0)
                {
                    time = 10000; riseFlag = true;
                }

                ManagementTraineePayRiseStandard currStandard = standards.Find(a => a.提资序数 == time); //当前标准
                if (currStandard != null)
                {
                    decimal rise_rate   = 0;
                    decimal year_salary = 0;

                    //计算年薪和增幅
                    if (currStandard.提资方式 == (int)RiseType.金额)
                    {
                        year_salary = currStandard.年薪;
                        if (last_year_salary > 0)
                        {
                            rise_rate = 100 * ((decimal)(year_salary - last_year_salary) / (decimal)last_year_salary);
                            rise_rate = Math.Round(rise_rate, 1, MidpointRounding.AwayFromZero);
                        }
                    }
                    else
                    {
                        if (riseFlag) //如果提资
                        {
                            rise_rate   = currStandard.增幅;
                            year_salary = Math.Round(last_year_salary * (100 + rise_rate) * (decimal)0.01, 1, MidpointRounding.AwayFromZero);
                        }
                        else
                        {
                            year_salary = last_year_salary;
                        }
                    }

                    ManagementTraineeSalaryPlan item = new ManagementTraineeSalaryPlan();
                    item.届别   = division;
                    item.岗位级别 = grade;
                    item.能力级别 = level;
                    item.专业属性 = type;
                    item.季度序数 = i;
                    item.年度序数 = i / 4;
                    item.季度年薪 = year_salary;
                    if (riseFlag && rise_rate > 0)
                    {
                        item.增幅 = rise_rate.ToString("#0.#") + "%";
                        if (time == 10000 && step != 0)
                        {
                            item.增幅 = "";
                        }
                    }
                    planList.Add(item);

                    last_year_salary = year_salary;
                }
            }
            //统计年薪
            foreach (ManagementTraineeSalaryPlan item in planList)
            {
                List <ManagementTraineeSalaryPlan> list = planList.FindAll(a => a.年度序数 == item.年度序数);
                item.年薪 = Math.Round(list.Sum(a => a.季度年薪) / (decimal)4.0, 1, MidpointRounding.AwayFromZero);
            }
            return(planList);
        }
        public static List <ManagementTraineePayStandard> CreatePayStandards(string emplid, int year)
        {
            EmployeeInfo employee = EmployeeInfo.GetFromCache(emplid);

            if (employee == null)
            {
                return(null);
            }

            //获取管培生基本信息
            ManagementTraineeInfo traineeInfo = ManagementTraineeInfo.GetManagementTraineeInfo(emplid);

            if (traineeInfo == null)
            {
                return(null);
            }

            DateTime start = new DateTime(year, 7, 1);
            ManagementTraineePayStandard first = CreateFirstStandard(emplid);
            //获取本年度评定前最后一次提资记录(增幅 > 0)
            ManagementTraineePayStandard latest = GetLatestRise(emplid, start);

            //如果没有找到提资记录,自动创建第一年的提资记录
            if (latest == null)
            {
                //第一年,已第一条记录为基准
                if (year == traineeInfo.入职时间.Year)
                {
                    latest = first;
                }
                else
                {
                    //创建入职当年的工资标准
                    CreatePayStandards(emplid, traineeInfo.入职时间.Year);
                    latest = GetLatestRise(emplid, start);
                }
            }
            if (latest == null)
            {
                return(null);                //如果找不到上一期提资记录,没法继续创建提资记录
            }
            //获取年度评定
            ManagementTraineeAbility ability = ManagementTraineeAbility.GetManagementTraineeAbility(emplid, year);
            string level = "A";
            string type  = traineeInfo.岗位级别 == "一级" ? traineeInfo.岗位类型 : traineeInfo.专业属性;
            //每年评定后自动产生后面四个季度的提资记录
            List <ManagementTraineePayStandard> list = new List <ManagementTraineePayStandard>();

            for (int i = 0; i < 4; i++)
            {
                decimal rise_rate    = 0;
                decimal year_salary  = latest.年薪;
                int     month_salary = latest.月薪;
                int     time         = -999; //如果次数是 -999 表示此季度不提资

                int quarter  = (i + 2) % 4 + 1;
                int the_year = quarter <= 2 ? year + 1 : year;

                int m = the_year - first.年份;
                int n = quarter - first.季度;
                int q = m * 4 + n; //距离起薪季度数

                int      x = the_year - latest.年份;
                int      y = quarter - latest.季度;
                int      quarterInterval = x * 4 + y; //距离最后一次提资季度数
                DateTime excuteStartTime = latest.开始执行时间.AddMonths(3 * quarterInterval);

                //获取提资序数
                //(第一年每半年固定提资)
                if (q <= 4)
                {
                    if (q == 2) //第一次提资
                    {
                        time = 1;
                    }
                    if (q == 4) //第二次提资
                    {
                        time = 2;
                    }
                }
                else
                {
                    if (ability == null)
                    {
                        continue;                  //如果还没有评定
                    }
                    level = ability.能力级别;
                    //默认本次提资序数=上一次提资序数+1
                    switch (level)
                    {
                    case "A":
                        if (quarterInterval >= 2)
                        {
                            time = latest.提资序数 + 1;
                        }
                        break;

                    case "B":
                        if (quarterInterval >= 3)
                        {
                            time = latest.提资序数 + 1;
                        }
                        break;

                    case "C":
                        if (quarterInterval >= 4)
                        {
                            time = latest.提资序数 + 1;
                        }
                        break;
                    }
                    //升阶(满足升阶条件,先升阶,每阶+100, 满阶是 10000)
                    double step = GetStep(traineeInfo.届别, traineeInfo.岗位级别, type, q);
                    if (step == 0)
                    {
                        time = 10000;
                    }
                    //2018-9-21 进入二阶段以后,达到也要达到提资时间间隔才能提资
                    if (step >= 2 && time > 0 && time < 100)
                    {
                        time = 100;
                    }
                }

                if (time == -999)
                {
                    continue;
                }

                ManagementTraineePayRiseStandard standard = ManagementTraineePayRiseStandard.GetManagementTraineePayRiseStandard(traineeInfo.届别, traineeInfo.岗位级别, type, level, time);
                if (standard == null)
                {
                    continue;                   //找不到提资标准
                }
                //获取增幅、年薪和月薪
                if (standard.提资方式 == (int)RiseType.金额)
                {
                    year_salary = standard.年薪;
                    rise_rate   = 100 * ((decimal)(year_salary - latest.年薪) / (decimal)latest.年薪);
                    rise_rate   = Math.Round(rise_rate, 1, MidpointRounding.AwayFromZero);
                }
                else
                {
                    rise_rate   = standard.增幅;
                    year_salary = Math.Round(latest.年薪 * (100 + rise_rate) * (decimal)0.01, 1, MidpointRounding.AwayFromZero);
                }

                month_salary = Convert.ToInt32((year_salary * (decimal)10000.0) / (decimal)12.0);

                ManagementTraineePayStandard new_item = AddManagementTraineePayStandard(emplid, employee.姓名, the_year, quarter, time);
                if (new_item != null)
                {
                    new_item.季度     = quarter;
                    new_item.年份     = the_year;
                    new_item.增幅     = rise_rate;
                    new_item.年薪     = year_salary;
                    new_item.月薪     = month_salary;
                    new_item.开始执行时间 = excuteStartTime;
                    new_item.Save();

                    list.Add(new_item);
                    latest = new_item;
                }
                if (time == 10000)
                {
                    break;                //已经满阶,退出
                }
            }
            return(list);
        }
        public static ManagementTraineeSalaryStandard Get(string division, string grade, string type, string level)
        {
            ManagementTraineeSalaryStandard standard = new ManagementTraineeSalaryStandard();

            List <ManagementTraineePayRiseStandard> items = ManagementTraineePayRiseStandard.GetManagementTraineePayRiseStandardList(division, grade, type, level);

            standard.届别   = division;
            standard.岗位级别 = grade;
            standard.类别   = type;
            standard.能力级别 = level;

            if (items.Count > 0)
            {
                standard.提资周期 = items[0].提资周期;

                ManagementTraineePayRiseStandard rise_item;
                //-------------------------------------------------------
                //一阶
                rise_item = items.Find(a => a.提资序数 == 0);
                if (rise_item != null)
                {
                    standard.一阶起薪 = rise_item.年薪;
                }

                rise_item = items.Find(a => a.提资序数 == 1);
                if (rise_item != null)
                {
                    standard.一阶增幅1 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 2);
                if (rise_item != null)
                {
                    standard.一阶增幅2 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 3);
                if (rise_item != null)
                {
                    standard.一阶增幅3 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 4);
                if (rise_item != null)
                {
                    standard.一阶增幅4 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 5);
                if (rise_item != null)
                {
                    standard.一阶增幅5 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 6);
                if (rise_item != null)
                {
                    standard.一阶增幅6 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 7);
                if (rise_item != null)
                {
                    standard.一阶增幅7 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 8);
                if (rise_item != null)
                {
                    standard.一阶增幅8 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 9);
                if (rise_item != null)
                {
                    standard.一阶增幅9 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 10);
                if (rise_item != null)
                {
                    standard.一阶增幅10 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 11);
                if (rise_item != null)
                {
                    standard.一阶增幅11 = rise_item.增幅;
                }

                //---------------------------------------------------------
                //二阶
                rise_item = items.Find(a => a.提资序数 == 100);
                if (rise_item != null)
                {
                    standard.二阶起薪 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 101);
                if (rise_item != null)
                {
                    standard.二阶增幅1 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 102);
                if (rise_item != null)
                {
                    standard.二阶增幅2 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 103);
                if (rise_item != null)
                {
                    standard.二阶增幅3 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 104);
                if (rise_item != null)
                {
                    standard.二阶增幅4 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 105);
                if (rise_item != null)
                {
                    standard.二阶增幅5 = rise_item.增幅;
                }

                rise_item = items.Find(a => a.提资序数 == 106);
                if (rise_item != null)
                {
                    standard.二阶增幅6 = rise_item.增幅;
                }

                //---------------------------------------------------------
                //满阶
                rise_item = items.Find(a => a.提资序数 == 10000);
                if (rise_item != null)
                {
                    standard.满阶起薪方式 = rise_item.提资方式;
                    standard.满阶起薪   = rise_item.提资方式 == 0 ? rise_item.增幅 : rise_item.年薪;
                }
            }

            return(standard);
        }
        public static ManagementTraineePayRiseStandard GetManagementTraineePayRiseStandard(Guid id)
        {
            ManagementTraineePayRiseStandard obj = (ManagementTraineePayRiseStandard)Session.DefaultSession.GetObjectByKey(typeof(ManagementTraineePayRiseStandard), id);

            return(obj);
        }