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); }
/// <summary> /// 创建包装业务员奖金 /// </summary> /// <param name="bpObj">BP入口参数:会计期间集合</param> /// <param name="dsPayment">付款通知单数据集</param> /// <param name="bonusCoefficient">奖金系数</param> /// <param name="degradationCoefficient">降价系数</param> /// <param name="DeliveryExpectDay">基准交期</param> private string CreatePackagingOperatorBonus(CalculateOperatorBonus bpObj, DataTable dsPayment, decimal packaingBonusCoefficient) { if (dsPayment == null || dsPayment.Rows.Count == 0) { return(""); } var groupOperators = dsPayment.Rows.Cast <DataRow>().GroupBy(t => t["Operators_Code"].ToString()); BonusOperatorDocType bonusType = BonusOperatorDocType.Finder.Find("BuzType=1 and IsCreatedByPush=1"); if (bonusType == null) { throw new Exception("请设置产品包装业务员单据类型并设置为上游单据推出"); } using (ISession session = Session.Open()) { BonusPackagingDoc bonusProduct = BonusPackagingDoc.Create(); bonusProduct.DocumentTypeKey = bonusType.Key; //单据类型 bonusProduct.BusinessDate = DateTime.Now; //业务日期 bonusProduct.Status = EnumBE.FICommonStatusEnum.Opened; if (bpObj.BonusCalcuteList[0].SOBAccountingPeriod != null && bpObj.BonusCalcuteList[0].SOBAccountingPeriod.AccountPeriod != null) { bonusProduct.AccountPeriodKey = bpObj.BonusCalcuteList[0].SOBAccountingPeriod.AccountPeriod.AccountingCalendarKey; //会计日历 } bonusProduct.CurrencyKey = Base.Currency.Currency.Finder.Find("Code='C001'").Key; //币种只会为人民币, bonusProduct.Oprator = Base.Context.LoginUser; bonusProduct.OprateDate = DateTime.Now; //设置默认行号 GetProfileValueProxy lineNo = new GetProfileValueProxy(); lineNo.ProfileCode = "SysLineNo"; PVDTOData pVTDOData = lineNo.Do(); string row = pVTDOData.ProfileValue; //根据业务员分组后的付款通知单数据 foreach (var groupOperator in groupOperators) { decimal sumPayment = 0; //付款单总额, decimal sumPerformance = 0; //业绩单总额 decimal productBonusTotal = 0; //新产品奖金合计 decimal depreciateBonusTotal = 0; //降价奖金合计 decimal bonusTotal = 0; //奖金合计 long operatorsKey = Convert.ToInt64(groupOperator.First <DataRow>()["Operators"].ToString()); long dept = Convert.ToInt64(groupOperator.First <DataRow>()["Department"].ToString()); BonusPackagingDocLine productLine = BonusPackagingDocLine.Create(bonusProduct); //业务员奖金明细行 productLine.DocLineNo = Convert.ToInt32(row); //行号 if (operatorsKey > 0) { productLine.OperatorsKey = CBO.HR.Operator.Operators.Finder.FindByID(operatorsKey).Key;//业务员 } if (dept > 0) { productLine.DepartmentKey = CBO.HR.Department.Department.Finder.FindByID(dept).Key;//部门 } //设置默认行号 string subRow = pVTDOData.ProfileValue; foreach (DataRow Operator in groupOperator) { if (Convert.ToInt32(Operator["SrcDocType"].ToString()) != EnumBE.PaySrcDocTypeEnum.Rcv.Value) { continue; } BonusPackagingDocSubLine subLine = BonusPackagingDocSubLine.Create(productLine); subLine.DocLineNo = Convert.ToInt32(subRow); subLine.OperatorsKey = CBO.HR.Operator.Operators.Finder.FindByID(operatorsKey).Key; //业务员 subLine.DepartmentKey = CBO.HR.Department.Department.Finder.FindByID(dept).Key; //部门 decimal payment = decimal.Parse(Operator["Payment"].ToString()); //付款单金额,转换成人民币 subLine.PaymentMey = payment; //付款单小类金额 sumPayment += payment; //获得产品系数档案 ProductCoefficient coefficient = ProductCoefficient.Finder.Find("ItemMaster.Code='" + Operator["Item_Code"].ToString() + "'"); if (coefficient == null) { throw new Exception("料品" + Operator["Item_Code"].ToString() + " " + Operator["Item_Name"].ToString() + "没有维护类别系数档案"); } subLine.CategoryCoefficient = coefficient; //类别系数 subLine.PaymentRowCount = groupOperator.Where <DataRow>(p => p["PaymentID"].ToString() == Operator["PaymentID"].ToString()).Count <DataRow>(); //付款单行数 decimal customerCoefficient = 1; //1、如果来源采购订单有接单客户则算取出客户的客户难易系数,否则默认1 if (Operator["Customer"].ToString() != "") { CBO.SCM.Customer.Customer customer = CBO.SCM.Customer.Customer.Finder.FindByID(Operator["Customer"].ToString()); if (customer != null && customer.DescFlexField.PubDescSeg24 != "") { customerCoefficient = decimal.Parse(customer.DescFlexField.PubDescSeg24); } } subLine.CustomerCoefficient = customerCoefficient; //客户难易系数 subLine.ItemCoefficient = packaingBonusCoefficient; //小类奖金系数 //计算奖金:付款通知单行数*类别系数*客户难易系数 + 付款单小类金额*千分之4*客户难易系数 subLine.Bonus = subLine.PaymentRowCount * coefficient.Coefficien * customerCoefficient * +payment * packaingBonusCoefficient * customerCoefficient; //subLine.ExpectMey = //预期奖金 subLine.PaymentDocKey = PaymentBE.Payment.Finder.FindByID(Operator["PaymentID"].ToString()).Key; subLine.PaymentDocNo = Operator["Payment_DocNo"].ToString(); subLine.ItemKey = CBO.SCM.Item.ItemMaster.Finder.FindByID(Operator["Item"].ToString()).Key; subLine.SrcDocLineNo = Convert.ToInt32(Operator["SrcDocLineNo"].ToString()); //降价奖金 subRow = (int.Parse(subRow) + int.Parse(pVTDOData.ProfileValue)).ToString();//自增行号 } productLine.SumPayment = sumPayment; productLine.BonusTotal = bonusTotal; row = (int.Parse(row) + int.Parse(pVTDOData.ProfileValue)).ToString();//自增行号 } session.Commit(); return(bonusProduct.DocNo); } }