二开维护核算单据成本
一、使用背景
1、成本模块刚上线,新老系统切换,新系统的成本需要和老系统保持一致,需要从其他系统对接过来;
2、部分类型单据需要使用企业特有的计价方法核算成本;
3、处理一些特殊业务(如核算组织内异价调拨)等需要维护核算单据成本的情况。
为方便二开逻辑对接写入核算单据成本,提供了成本维护接口处理,通过接口实现无需关注成本后台表逻辑及其关联性,解决原来直接更新后台容易出错,各种单据分散、学习成本高等对接困难问题,同时可以解决大数量下性能问题。
二、接口说明
1、接口方法
HSBillMaintainServiceHelper.UpdateHsBillPrice(Context ctx, OutStockAcctgParameters acctParams)
2、引用组件
Kingdee.K3.FIN.HS.ServiceHelper
3、前置条件
3.1、只能维护存货核算当前期间的单据,不能维护历史期间及未来期间的单据;
3.2、需要本期已经核算过,产生了核算单据(可以在核算单据查询中查到);
3.3、不能维护已固定成本的单据(如单据已经生成凭证或者入库单已经下推应付单产生钩稽日志等已经固定成本的情况下,如果再通过接口去维护成本会导致对账不平等数据异常)。
4、方法必选参数
Context ctx:上下文参数
OutStockAcctgParameters acctParam: 核算参数
核算参数对象里的必选参数:
AcctgSys :核算体系
AcctgOrg:核算组织
AcctPolicy:会计政策
NoUpdateAcctgBillCost:不更新已修改过的单据
WriteCostCalTable:写成本计算表
UserId:用户ID
YearPeriodInfo.Year:会计年度
YearPeriodInfo.Period:会计期间
IsExpenseCal :是否按费用项目核算
BillFromEntrys:待维护的单据信息集合
单据集合对象里的必选参数:
BillFromId:单据标识
BillEntryId:单据分录内码
Price:单价,需要精度处理截位,保持和币别单价精度一致,未截位会导致余额小数位异常
Amount:金额,需要精度处理截位,保持和币别金额精度一致,未截位会导致余额小数位异常
SeqId:出入库序列内码(表T_HS_OUTINSTOCKSEQ的主键FENTRYID,可以与单据数据关联获取到)
ExpenseDatas:费用项目字典集合,此集合的金额合计需要和Amount相等,如果未启用费用项目核算, 直接给默认材料ID和Amount值
ExpenseDatas对象里面的必选参数:
Key:费用项目ID
Value:费用项目金额,需要精度处理截位,保持和币别金额精度一致
5、方法可选重要参数
OutStockAcctgParameters .Option:核算参数拓展参数
MaintainCostUnUpdateBalance:维护成本后是否不更新余额
此参数设置为“true”时(推荐),只会更新核算单据相关内容,不会去更新对应维度的期末余额数据,如果当更新大批 量单据时,建议设置为“true”,可以极大提升效率,但维护后必须重新核算(并且核算时需要勾选“出库核算不更新已修改成本的核算单据成本”,如果未更新此参数,会导致维护的成本不生效),重新核算后,维护成本单据会固定成本,如果是维护的是入库单据将参与计价方法核算,并重新计算余额;
如果参数设置为false或者不设置时,会根据每笔维护的核算单据重新计算期末余额,维护完成后不需要重新核算,但是维护的单据如果是入库单也不会参与计价方法核算(如果启用了产品成本核算,维护了领料单等未重新成本计算的话,会导致关联成本不正常,也需要重新核算),适用于修改少量出库单据,或者不需要参与计算的入库单据。
设置此参数示例: acctParam.Option.SetVariableValue("MaintainCostUnUpdateBalance", true);
三、接口示例
/// <summary> /// 批量维护核算单据成本 /// </summary> /// <param name="ctx"></param> /// <param name="acctgSysId">核算体系ID</param> /// <param name="acctgOrgId">核算组织ID</param> /// <param name="acctPolicyId">会计政策ID</param> /// <returns></returns> private bool UpdateAcctgBillCost(Context ctx, long acctgSysId, long acctgOrgId, long acctPolicyId) { // 是否启用费用项目核算 bool isExpCost = CommonServiceHelper.GetIsCalByExpenItem(ctx, acctPolicyId); // 默认材料费用ID long defaultMatExpId = CommonServiceHelper.GetDefaultMaterialExpenseID(ctx); // 会计政策对应本位币 long currencyId = CommonServiceHelper.GetCurrencyIDByAcctPolicy(ctx, acctPolicyId); // 单价精度 int priceDecimal = 6; // 金额精度 int amountDecimal = CommonServiceHelper.GetCurrencyDecimal(ctx, currencyId, out priceDecimal); // 获取当前年期 JSONObject yearperiod = CommonServiceHelper.GetSystemCurYearPeriod(ctx, acctgSysId, acctgOrgId, acctPolicyId); int year = yearperiod.GetInt("CurYear"); int period = yearperiod.GetInt("CurPeriod"); // 例如修改销售出库单业务日期为'2022/01/01'的单据,成本价为100.123456,具体的数据来源可以根据实际需求获取,此处仅演示使用方式 // 获取核算体系+核算组织+会计政策+年+期唯一码 long acctgId = CommonServiceHelper.GetAcctgID(ctx, acctgSysId, acctgOrgId, acctPolicyId, year, period); // 获取所需数据源信息 StringBuilder sqlStr = new StringBuilder(); sqlStr.AppendFormat("SELECT t2.FENTRYID, "); sqlStr.AppendFormat(" SEQ.FENTRYID FSEQID "); sqlStr.AppendFormat("FROM T_SAL_OUTSTOCK T1 "); sqlStr.AppendFormat(" INNER JOIN T_SAL_OUTSTOCKENTRY T2 "); sqlStr.AppendFormat(" ON T1.FID = t2.FID "); sqlStr.AppendFormat(" INNER JOIN T_HS_OUTINSTOCKSEQ SEQ "); sqlStr.AppendFormat(" ON T2.FENTRYID = seq.FBILLENTRYID "); sqlStr.AppendFormat(" AND seq.FBILLFROMID = 'SAL_OUTSTOCK' "); sqlStr.AppendFormat("WHERE SEQ.FACCTGID = {0} and T1.FDATE='2022/01/01'", acctgId); var dys = Kingdee.BOS.ServiceHelper.DBServiceHelper.ExecuteDynamicObject(this.Context, sqlStr.ToString()); if (dys.IsEmpty()) { this.View.ShowMessage("未获取到需要更新的数据,请检查!"); return false; } List<AcctgBillCostInfo> acctgBillCostInfos = new List<AcctgBillCostInfo>(); foreach (DynamicObject item in dys) { AcctgBillCostInfo acctgBillCost = new AcctgBillCostInfo(); // 单据标识,可以从bos ide 中查到 acctgBillCost.BillFromId = "SAL_OUTSTOCK"; // 单据分录内码,根据实际获取值设置,例如销售出库单的分录内码为T_SAL_OUTSTOCKENTRY表的FENTRYID字段 acctgBillCost.BillEntryId = Convert.ToInt64(item["FENTRYID"]); // 出入库序列内码通过T_HS_OUTINSTOCKSEQ表获取FENTRYID值 acctgBillCost.SeqId = Convert.ToInt64(item["FSEQID"]); // 成本价,需要按币别单价精度截位 acctgBillCost.Price = Math.Round((decimal)100.123456, priceDecimal); // 总成本,需要按币别金额精度截位,总成本=单价*数量,假设数量10, acctgBillCost.Amount = Math.Round(acctgBillCost.Price*10, amountDecimal); // 未启用按费用项目核算的情况下,费用项目给默认材料 if (!isExpCost) { acctgBillCost.ExpenseDatas.Add(defaultMatExpId, acctgBillCost.Amount); } // 启用按费用项目核算的情况下,根据实际需求设置费用项目金额 else { // 设置各个费用项目值 } acctgBillCostInfos.Add(acctgBillCost); } if (acctgBillCostInfos.IsEmpty()) { // 提示信息,如果是后台服务可以通过写日志记录 this.View.ShowMessage("未获取到需要更新的数据,请检查!"); return false; } // 初始化相关参数 OutStockAcctgParameters acctParams = new OutStockAcctgParameters(); acctParams.AcctgSys = new NumberNameId() { Id = this.AcctgSystemId }; acctParams.AcctgOrg = new NumberNameId() { Id = this.AcctgOrgId }; acctParams.AcctPolicy = new NumberNameId() { Id = this.AcctPolicyId }; acctParams.NoUpdateAcctgBillCost = true; acctParams.WriteCostCalTable = true; acctParams.WriteExpCalDetail = false; acctParams.UserId = ctx.UserId; acctParams.BillFromEntrys = acctgBillCostInfos; acctParams.YearPeriodInfo.Year = year; acctParams.YearPeriodInfo.Period = period; acctParams.Option.SetVariableValue("MaintainCostUnUpdateBalance", true); acctParams.IsExpenseCal = isExpCost; var retValue = HSBillMaintainServiceHelper.UpdateHsBillPrice(ctx, acctParams); if (retValue) { this.View.ShowMessage(string.Format("成功更新{0}条数据,请重新核算!", acctParams.BillFromEntrys.Count)); } else { this.View.ShowErrMessage("更新失败!"); } return retValue; }
二开维护核算单据成本
本文2024-09-23 02:11:49发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-150844.html