Ejemplo n.º 1
0
        private BonusRecordDTO GetCalculationRecord(SelectOperatorBonus bpObj)
        {
            BonusRecordDTO bonusRecord = new BonusRecordDTO();                                                                                 //返回值
            List <int>     yearList    = new List <int>();                                                                                     //返回会计年度
            List <BonusCalculateRecordBE.BonusCalculateRecordDTO> calculateList = new List <BonusCalculateRecordBE.BonusCalculateRecordDTO>(); //返回奖金计算记录
            BonusCalculateRecordDTO calculateDto = null;                                                                                       //返回奖金计算

            #region 得到本年度的会计期间
            //主账薄,法人组织得到帐薄
            UFIDA.U9.Base.SOB.SetofBooks book = UFIDA.U9.Base.SOB.SetofBooks.Finder.Find("OrgFunction=@OrgFunction and SOBType=@SOBType and Org=@Org", new OqlParam("OrgFunction", UFIDA.U9.Base.SOB.OrgFunctionEnum.LegacyOrg.Value), new OqlParam("SOBType", UFIDA.U9.Base.SOB.SOBTypeEnum.PrimarySOB.Value), new OqlParam("Org", UFIDA.U9.Base.Context.LoginOrg.ID));
            if (book == null)
            {
                throw new Exception("没有主账薄");
            }

            //UFIDA.U9.Base.Account.AccountPeriod account = UFIDA.U9.Base.Account.AccountPeriod.Finder.Find("Year=@Year", new OqlParam("Year", bpObj.Year));
            //if (account == null)
            //    return null;

            UFIDA.U9.Base.SOB.SOBAccountingPeriod.EntityList sobGetYearList = UFIDA.U9.Base.SOB.SOBAccountingPeriod.Finder.FindAll("SetofBooks=@SetofBooks", new OqlParam("SetofBooks", book.ID));
            foreach (SOBAccountingPeriod sob in sobGetYearList)
            {
                if (!yearList.Contains(sob.Year))
                {
                    yearList.Add(sob.Year);
                }
            }
            UFIDA.U9.Base.SOB.SOBAccountingPeriod.EntityList sobList = UFIDA.U9.Base.SOB.SOBAccountingPeriod.Finder.FindAll("Year=@Year and SetofBooks=@SetofBooks", new OqlParam("Year", bpObj.Year), new OqlParam("SetofBooks", book.ID));

            #endregion
            //得到奖金计算记录
            BonusCalculateRecord record = null;
            if (bpObj.Type == 0) //采购 业务员奖金计算记录
            {
                foreach (SOBAccountingPeriod sob in sobList)
                {
                    calculateDto = new BonusCalculateRecordDTO();
                    record       = BonusCalculateRecord.Finder.Find("SOBAccountingPeriod=@SOBAccountingPeriod and SourceType=0", new OqlParam(sob.ID));
                    if (record != null)//已计算奖金
                    {
                        calculateDto.SOBAccountingPeriod = record.SOBAccountingPeriod;
                        calculateDto.PeriodStatus        = record.PeriodStatus;
                        calculateDto.OprateTime          = record.OprateTime;
                        calculateDto.Oprator             = record.Oprator;
                        calculateDto.ID            = record.ID;
                        calculateDto.OperatorBonus = record.OperatorBonus;
                    }
                    else //未计算奖金
                    {
                        calculateDto.SOBAccountingPeriod = sob;
                        calculateDto.PeriodStatus        = EnumBE.PeriodStatusEnum.NoCalculate;
                    }

                    calculateList.Add(calculateDto);
                }
            }
            else if (bpObj.Type == 1)//包装业务员奖金计算记录
            {
                foreach (SOBAccountingPeriod sob in sobList)
                {
                    calculateDto = new BonusCalculateRecordDTO();
                    record       = BonusCalculateRecord.Finder.Find("SOBAccountingPeriod=@SOBAccountingPeriod and SourceType=1", new OqlParam(sob.ID));
                    if (record != null)//已计算奖金
                    {
                        calculateDto.SOBAccountingPeriod = record.SOBAccountingPeriod;
                        calculateDto.PeriodStatus        = record.PeriodStatus;
                        calculateDto.OprateTime          = record.OprateTime;
                        calculateDto.Oprator             = record.Oprator;
                        calculateDto.ID            = record.ID;
                        calculateDto.OperatorBonus = record.OperatorBonus;
                    }
                    else //未计算奖金
                    {
                        calculateDto.SOBAccountingPeriod = sob;
                        calculateDto.PeriodStatus        = EnumBE.PeriodStatusEnum.NoCalculate;
                    }
                    calculateList.Add(calculateDto);
                }
            }
            bonusRecord.ListYear             = yearList;
            bonusRecord.BonusCalculateRecord = calculateList;
            return(bonusRecord);
        }
        private ErrorMessageDTO CalculateAction(CalculateOperatorBonus bpObj)
        {
            ErrorMessageDTO errorDot = new ErrorMessageDTO();

            // 1、 bpObj.Type 为0计算采购业务员奖金,为1计算包装业务员奖金;
            //2、bpObj.OperatorsList为空或者bpObj.OperatorsList.Count为0计算指定会计期间内的所有业务员,反之计算指定业务员奖金
            //操作事件区分,0计算,1补算,2取消计算
            if (bpObj.CalculateType == 0)
            {
                #region 计算奖金功能
                //计算奖金
                #region 计算前校验
                //1、所选会计期间状态必须为“未计算”,
                foreach (BonusCalculateRecordBE.BonusCalculateRecordDTO dto in bpObj.BonusCalcuteList)
                {
                    //勾选的会计期间必须是当前月度前的会计期间并且期间状态是“未计算”的;
                    if (dto.PeriodStatus == EnumBE.PeriodStatusEnum.Calculate || dto.PeriodStatus == EnumBE.PeriodStatusEnum.RepairCalculate)
                    {
                        throw new Exception("会计期间" + dto.SOBAccountingPeriod.DisplayName + "已计算奖金");
                    }
                    if (dto.SOBAccountingPeriod != null && dto.SOBAccountingPeriod.DisplayName != "")
                    {
                        if (Convert.ToDateTime(dto.SOBAccountingPeriod.DisplayName) >= Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM")))
                        {
                            throw new Exception("会计期间" + dto.SOBAccountingPeriod.DisplayName + "必须是当前月度前的会计期间");
                        }
                    }
                }
                //2、勾选的会计期间前一个会计期间必须已完成计算,
                //找到最小的会计期间,判断它的前一个会计期间是否已计算
                var minPeriodNumber = bpObj.BonusCalcuteList.Min <BonusCalculateRecordDTO>(p => p.SOBAccountingPeriod.Number);
                if ((Convert.ToInt32(minPeriodNumber) - 10) > 0) //前一个会计期间不为XXXX-01(即本年度第一个会计期间)
                {
                    //勾选的最小会计期间前一个会计期间必须已完成计算,
                    BonusCalculateRecordBE.BonusCalculateRecord record = BonusCalculateRecordBE.BonusCalculateRecord.Finder.Find("SourceType=" + bpObj.Type + " and SOBAccountingPeriod.Year=" + bpObj.Year + " and SOBAccountingPeriod.Number=" + (Convert.ToInt32(minPeriodNumber) - 10) + "");
                    //BonusCalculateRecordBE.BonusCalculateRecord.EntityList recoudList = BonusCalculateRecordBE.BonusCalculateRecord.Finder.FindAll("1=1");
                    if (record == null || record.PeriodStatus == EnumBE.PeriodStatusEnum.NoCalculate)
                    {
                        throw new Exception("勾选的最小会计期间前一个会计期间必须已完成计算");
                    }
                }
                //3、如果勾选多个,则必须是连续性的会计期间,中间不允许出现未计算的或者没有勾选的;
                //先排序,再判断是否连续会计期间
                IEnumerable <BonusCalculateRecordDTO> recordDTO = from calDTO in bpObj.BonusCalcuteList orderby calDTO.SOBAccountingPeriod.Number descending select calDTO;
                int number = 0;//判断是否连续的标志
                foreach (BonusCalculateRecordDTO bonusDTO in recordDTO)
                {
                    if (number != 0)
                    {
                        if (number != bonusDTO.SOBAccountingPeriod.Number)
                        {
                            throw new Exception("请勾选连续的会计期间进行计算");
                        }
                    }
                    number = bonusDTO.SOBAccountingPeriod.Number;
                }
                #endregion 校验结束
                #region 校验通过,计算奖金
                //奖金计算时,不区分组织,即统计发生在勾选的会计期间范围内的已审核的付款通知单,
                //并且付款通知单来源采购订单的业务员类型为产品采购的(组织间的抛单业务除外),
                //根据业务员进行分组,计算业务员奖金,

                #region 获取预置参数
                decimal bonusCoefficient         = 0;                                                                 //奖金系数
                decimal degradationCoefficient   = 0;                                                                 //降价系数
                decimal packaingBonusCoefficient = 0;                                                                 //包装奖金系数
                int     deliveryExpectDay        = 0;                                                                 //交货基准交期
                GetSysteParma(bonusCoefficient, degradationCoefficient, packaingBonusCoefficient, deliveryExpectDay); //获取预置参数值
                #endregion

                #region 查询付款通知单
                //获得会计期间的最大、最小时间
                if (recordDTO == null || recordDTO.Count <BonusCalculateRecordDTO>() == 0)
                {
                    throw new Exception("请选择计算的会计期间");
                }
                //会计期间的最小时间
                string startTime = DateTime.Parse(recordDTO.First <BonusCalculateRecordDTO>().SOBAccountingPeriod.DisplayName).ToString("yyyy-MM-01 00:00:00");
                //string endTime = DateTime.Parse(recordDTO.Last<BonusCalculateRecordDTO>().SOBAccountingPeriod.DisplayName).ToString("yyyy-MM-
                //会计期间的最大时间
                int      year     = DateTime.Parse(recordDTO.Last <BonusCalculateRecordDTO>().SOBAccountingPeriod.DisplayName).Year;
                int      month    = DateTime.Parse(recordDTO.Last <BonusCalculateRecordDTO>().SOBAccountingPeriod.DisplayName).Month;
                int      days     = DateTime.DaysInMonth(year, month);
                DateTime datetime = new DateTime(year, month, 1);
                string   endTime  = datetime.AddDays(days - 1).ToString("yyyy-MM-dd 23:59:59");
                //获取付款通知单数据集
                DataTable tablePayment = GetPaymentData(bpObj, DateTime.Parse(startTime), DateTime.Parse(endTime));
                #endregion
                string docNo = "";
                #region 生成业务员奖金
                if (bpObj.Type == 0)//生成采购业务员奖金
                {
                    docNo = CreateProductOperatorBonus(bpObj, tablePayment, bonusCoefficient, degradationCoefficient, deliveryExpectDay);
                }
                else //生成包装业务员奖金
                {
                    docNo = CreatePackagingOperatorBonus(bpObj, tablePayment, packaingBonusCoefficient);
                }
                #endregion

                #region 生成奖金计算记录
                using (ISession session = Session.Open())
                {
                    BonusCalculateRecord bonusRecord = null;
                    foreach (BonusCalculateRecordDTO bonusDTO in bpObj.BonusCalcuteList)
                    {
                        bonusRecord = BonusCalculateRecord.Create();
                        if (bpObj.Type == 0)
                        {
                            bonusRecord.SourceType = EnumBE.BonusOperatorsTypeEnum.ProductOperators;
                        }
                        else
                        {
                            bonusRecord.SourceType = EnumBE.BonusOperatorsTypeEnum.PackagingOperators;
                        }
                        bonusRecord.SOBAccountingPeriodKey = bonusDTO.SOBAccountingPeriod.Key;
                        bonusRecord.Oprator       = UFIDA.U9.Base.Context.LoginUser;
                        bonusRecord.OprateTime    = DateTime.Now;
                        bonusRecord.PeriodStatus  = EnumBE.PeriodStatusEnum.Calculate;
                        bonusRecord.Org           = UFIDA.U9.Base.Context.LoginOrg;
                        bonusRecord.OperatorBonus = docNo;
                    }
                    session.Commit();
                }
                #endregion

                if (docNo != "")
                {
                    //生成成功,发送消息
                    List <long> recever = new System.Collections.Generic.List <long>();
                    recever.Add(Convert.ToInt64(UFIDA.U9.Base.Context.LoginUserID));
                    UFIDA.U9.Cust.GS.FI.FIBP.PubBP.SendMessageExtend.SendMessage("计算业务员奖金完成,生成单号" + docNo, "业务员奖金计算完成通知", recever, UFIDA.U9.BS.Notification.PriorityEnum.Medium);
                }
                #endregion
                #endregion 计算End
            }
            else if (bpObj.CalculateType == 1)
            {
                #region 补算
                #region 补算前校验
                //可以通过计算范围选择性的选择业务员进行奖金的补算,补算可以跨月进行,补算完后,记录补算的结果,并产生差异明细;
                foreach (BonusCalculateRecordBE.BonusCalculateRecordDTO dto in bpObj.BonusCalcuteList)
                {
                    //勾选的会计期间必须是当前月度前的会计期间并且期间状态是“未计算”的;
                    if (dto.PeriodStatus == EnumBE.PeriodStatusEnum.NoCalculate)
                    {
                        throw new Exception("会计期间" + dto.SOBAccountingPeriod.DisplayName + "未计算奖金,不能补算");
                    }
                }
                #endregion 补算前校验End
                #region 获取预置参数
                decimal bonusCoefficient         = 0;                                                                 //奖金系数
                decimal degradationCoefficient   = 0;                                                                 //降价系数
                decimal packaingBonusCoefficient = 0;                                                                 //包装奖金系数
                int     deliveryExpectDay        = 0;                                                                 //交货基准交期
                GetSysteParma(bonusCoefficient, degradationCoefficient, packaingBonusCoefficient, deliveryExpectDay); //获取预置参数值
                #endregion

                #region 补算
                //获取付款通知单数据集,因为可以跨月计算,所以根据每个会计期间查询
                DataTable tablePayment = GetPaymentData(bpObj, DateTime.Now, DateTime.Now);
                string    docNo        = "";
                #region 生成业务员奖金
                if (bpObj.Type == 0)//生成采购业务员奖金
                {
                    docNo = CreateProductOperatorBonus(bpObj, tablePayment, bonusCoefficient, degradationCoefficient, deliveryExpectDay);
                }
                else //生成包装业务员奖金
                {
                    docNo = CreatePackagingOperatorBonus(bpObj, tablePayment, packaingBonusCoefficient);
                }
                #endregion

                #region 生成奖金计算记录
                using (ISession session = Session.Open())
                {
                    BonusCalculateRecord bonusRecord = null;
                    foreach (BonusCalculateRecordDTO bonusDTO in bpObj.BonusCalcuteList)
                    {
                        bonusRecord = BonusCalculateRecord.Create();
                        if (bpObj.Type == 0)
                        {
                            bonusRecord.SourceType = EnumBE.BonusOperatorsTypeEnum.ProductOperators;
                        }
                        else
                        {
                            bonusRecord.SourceType = EnumBE.BonusOperatorsTypeEnum.PackagingOperators;
                        }
                        bonusRecord.SOBAccountingPeriodKey = bonusDTO.SOBAccountingPeriod.Key;
                        bonusRecord.Oprator             = UFIDA.U9.Base.Context.LoginUser;
                        bonusRecord.OprateTime          = DateTime.Now;
                        bonusRecord.PeriodStatus        = EnumBE.PeriodStatusEnum.RepairCalculate;//补算
                        bonusRecord.Org                 = UFIDA.U9.Base.Context.LoginOrg;
                        bonusRecord.RepairOperatorBonus = docNo;
                    }
                    session.Commit();
                }
                #endregion

                if (docNo != "")
                {
                    //生成成功,发送消息
                    List <long> recever = new System.Collections.Generic.List <long>();
                    recever.Add(Convert.ToInt64(UFIDA.U9.Base.Context.LoginUserID));
                    UFIDA.U9.Cust.GS.FI.FIBP.PubBP.SendMessageExtend.SendMessage("计算业务员奖金完成,生成单号" + docNo, "业务员奖金计算完成通知", recever, UFIDA.U9.BS.Notification.PriorityEnum.Medium);
                }
                #endregion 补算 End
                #endregion 补算
            }
            else if (bpObj.CalculateType == 2)
            {
                #region 取消计算
                //1、勾选的会计期间前后的会计期间状态必须是“未计算”的,否则提示不允许取消;
                //2、校验通过后,删除勾选的会计期间对应的业务员奖金计算结果
                #region 取消计算前校验
                foreach (BonusCalculateRecordBE.BonusCalculateRecordDTO dto in bpObj.BonusCalcuteList)
                {
                    //勾选的会计期间必须是当前月度前的会计期间并且期间状态是“未计算”的;
                    if (dto.PeriodStatus == EnumBE.PeriodStatusEnum.NoCalculate)
                    {
                        throw new Exception("会计期间" + dto.SOBAccountingPeriod.DisplayName + "未计算奖金,无需取消计算");
                    }
                }
                #endregion 取消计算前校验 end

                #region 取消计算
                using (ISession session = Session.Open())
                {
                    BonusProductDoc   bonusProduct   = null;
                    BonusPackagingDoc bonusPackaging = null;
                    foreach (BonusCalculateRecordBE.BonusCalculateRecordDTO dto in bpObj.BonusCalcuteList)
                    {
                        if (dto.ID > 0)
                        {
                            if (bpObj.Type == 0)//采购业务员奖金
                            {
                                bonusProduct = BonusProductDoc.Finder.Find("OperatorBonus='" + dto.OperatorBonus + "'");
                                if (bonusProduct != null)
                                {
                                    bonusProduct.Remove();
                                }
                            }
                            else if (bpObj.Type == 1)//包装业务员奖金
                            {
                                bonusPackaging = BonusPackagingDoc.Finder.Find("OperatorBonus='" + dto.OperatorBonus + "'");
                                if (bonusPackaging != null)
                                {
                                    bonusPackaging.Remove();
                                }
                            }
                        }
                    }
                    session.Commit();
                }
                #endregion

                #endregion
            }
            return(errorDot);
        }